diff --git a/.rubocop.yml b/.rubocop.yml index 73cfe629..73161097 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,7 @@ --- require: - rubocop-performance + - rubocop-rspec AllCops: DisplayCopNames: true diff --git a/Gemfile b/Gemfile index 257b78c9..6ff46eff 100644 --- a/Gemfile +++ b/Gemfile @@ -1,50 +1,53 @@ +# frozen_string_literal: true + source "https://rubygems.org" -gem "nokogiri", '~> 1.13', '>= 1.13.4' +gem "nokogiri", '~> 1.13', '>= 1.13.4' gemspec -gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" -gem 'json-canonicalization',git: "https://github.com/dryruby/json-canonicalization",branch: "develop" +gem 'json-canonicalization', git: "https://github.com/dryruby/json-canonicalization", branch: "develop" +gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" group :development do - gem 'ebnf', git: "https://github.com/dryruby/ebnf", branch: "develop" - gem 'json-ld-preloaded', github: "ruby-rdf/json-ld-preloaded", branch: "develop" - gem 'ld-patch', github: "ruby-rdf/ld-patch", branch: "develop" - gem 'linkeddata', git: "https://github.com/ruby-rdf/linkeddata", branch: "develop" - gem 'rack-linkeddata', git: "https://github.com/ruby-rdf/rack-linkeddata", branch: "develop" - gem 'rdf-aggregate-repo', git: "https://github.com/ruby-rdf/rdf-aggregate-repo", branch: "develop" - gem 'rdf-isomorphic', git: "https://github.com/ruby-rdf/rdf-isomorphic", branch: "develop" - gem 'rdf-json', github: "ruby-rdf/rdf-json", branch: "develop" - gem 'rdf-microdata', git: "https://github.com/ruby-rdf/rdf-microdata", branch: "develop" - gem 'rdf-n3', github: "ruby-rdf/rdf-n3", branch: "develop" - gem 'rdf-normalize', github: "ruby-rdf/rdf-normalize", branch: "develop" - gem 'rdf-rdfa', git: "https://github.com/ruby-rdf/rdf-rdfa", branch: "develop" - gem 'rdf-rdfxml', git: "https://github.com/ruby-rdf/rdf-rdfxml", branch: "develop" - gem 'rdf-reasoner', github: "ruby-rdf/rdf-reasoner", branch: "develop" - gem 'rdf-spec', git: "https://github.com/ruby-rdf/rdf-spec", branch: "develop" - gem 'rdf-tabular', github: "ruby-rdf/rdf-tabular", branch: "develop" - gem 'rdf-trig', git: "https://github.com/ruby-rdf/rdf-trig", branch: "develop" - gem 'rdf-trix', github: "ruby-rdf/rdf-trix", branch: "develop" - gem 'rdf-turtle', git: "https://github.com/ruby-rdf/rdf-turtle", branch: "develop" - gem 'rdf-vocab', git: "https://github.com/ruby-rdf/rdf-vocab", branch: "develop" - gem 'rdf-xsd', git: "https://github.com/ruby-rdf/rdf-xsd", branch: "develop" - gem 'sinatra-linkeddata', git: "https://github.com/ruby-rdf/sinatra-linkeddata", branch: "develop" - gem 'shex', github: "ruby-rdf/shex", branch: "develop" - gem 'sparql', git: "https://github.com/ruby-rdf/sparql", branch: "develop" - gem 'sparql-client', git: "https://github.com/ruby-rdf/sparql-client", branch: "develop" - gem 'sxp', git: "https://github.com/dryruby/sxp.rb", branch: "develop" - gem 'fasterer' gem 'earl-report' - gem 'ruby-prof', platforms: :mri + gem 'ebnf', git: "https://github.com/dryruby/ebnf", branch: "develop" + gem 'fasterer' + gem 'json-ld-preloaded', github: "ruby-rdf/json-ld-preloaded", branch: "develop" + gem 'ld-patch', github: "ruby-rdf/ld-patch", branch: "develop" + gem 'linkeddata', git: "https://github.com/ruby-rdf/linkeddata", branch: "develop" + gem 'rack-linkeddata', git: "https://github.com/ruby-rdf/rack-linkeddata", branch: "develop" + gem 'rdf-aggregate-repo', git: "https://github.com/ruby-rdf/rdf-aggregate-repo", branch: "develop" + gem 'rdf-isomorphic', git: "https://github.com/ruby-rdf/rdf-isomorphic", branch: "develop" + gem 'rdf-json', github: "ruby-rdf/rdf-json", branch: "develop" + gem 'rdf-microdata', git: "https://github.com/ruby-rdf/rdf-microdata", branch: "develop" + gem 'rdf-n3', github: "ruby-rdf/rdf-n3", branch: "develop" + gem 'rdf-normalize', github: "ruby-rdf/rdf-normalize", branch: "develop" + gem 'rdf-rdfa', git: "https://github.com/ruby-rdf/rdf-rdfa", branch: "develop" + gem 'rdf-rdfxml', git: "https://github.com/ruby-rdf/rdf-rdfxml", branch: "develop" + gem 'rdf-reasoner', github: "ruby-rdf/rdf-reasoner", branch: "develop" + gem 'rdf-spec', git: "https://github.com/ruby-rdf/rdf-spec", branch: "develop" + gem 'rdf-tabular', github: "ruby-rdf/rdf-tabular", branch: "develop" + gem 'rdf-trig', git: "https://github.com/ruby-rdf/rdf-trig", branch: "develop" + gem 'rdf-trix', github: "ruby-rdf/rdf-trix", branch: "develop" + gem 'rdf-turtle', git: "https://github.com/ruby-rdf/rdf-turtle", branch: "develop" + gem 'rdf-vocab', git: "https://github.com/ruby-rdf/rdf-vocab", branch: "develop" + gem 'rdf-xsd', git: "https://github.com/ruby-rdf/rdf-xsd", branch: "develop" + gem 'ruby-prof', platforms: :mri + gem 'shex', github: "ruby-rdf/shex", branch: "develop" + gem 'sinatra-linkeddata', git: "https://github.com/ruby-rdf/sinatra-linkeddata", branch: "develop" + gem 'sparql', git: "https://github.com/ruby-rdf/sparql", branch: "develop" + gem 'sparql-client', git: "https://github.com/ruby-rdf/sparql-client", branch: "develop" + gem 'sxp', git: "https://github.com/dryruby/sxp.rb", branch: "develop" end group :development, :test do - gem 'simplecov', '~> 0.21', platforms: :mri - gem 'simplecov-lcov', '~> 0.8', platforms: :mri - gem 'psych', platforms: [:mri, :rbx] gem 'benchmark-ips' + gem 'psych', platforms: %i[mri rbx] gem 'rake' gem 'rubocop' gem 'rubocop-performance' + gem 'rubocop-rspec' + gem 'simplecov', '~> 0.21', platforms: :mri + gem 'simplecov-lcov', '~> 0.8', platforms: :mri end group :debug do diff --git a/Rakefile b/Rakefile index 14cc84ab..e39ec7da 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rubygems' -task default: [ :spec ] +task default: [:spec] namespace :gem do desc "Build the json-ld-#{File.read('VERSION').chomp}.gem file" @@ -17,18 +19,18 @@ end require 'rspec/core/rake_task' desc 'Run specifications' RSpec::Core::RakeTask.new(:spec) do |spec| - spec.rspec_opts = %w(--options spec/spec.opts) if File.exists?('spec/spec.opts') + spec.rspec_opts = %w[--options spec/spec.opts] if File.exist?('spec/spec.opts') end desc "Generate schema.org context" task :schema_context do - %x( + ` script/gen_context https://schema.org/docs/schema_org_rdfa.html \ --vocab http://schema.org/ \ --prefix 'schema http://schema.org/' \ --body --hier \ --o etc/schema.org.jsonld - ) + ` end desc "Create concatenated test manifests" @@ -37,68 +39,73 @@ file "etc/manifests.nt" do require 'json/ld' require 'rdf/ntriples' graph = RDF::Graph.new do |g| - %w( https://w3c.github.io/json-ld-api/tests/compact-manifest.jsonld + %w[ https://w3c.github.io/json-ld-api/tests/compact-manifest.jsonld https://w3c.github.io/json-ld-api/tests/expand-manifest.jsonld https://w3c.github.io/json-ld-api/tests/flatten-manifest.jsonld https://w3c.github.io/json-ld-api/tests/fromRdf-manifest.jsonld https://w3c.github.io/json-ld-api/tests/html-manifest.jsonld https://w3c.github.io/json-ld-api/tests/remote-doc-manifest.jsonld https://w3c.github.io/json-ld-api/tests/toRdf-manifest.jsonld - https://w3c.github.io/json-ld-framing/tests/frame-manifest.jsonld - ).each do |man| + https://w3c.github.io/json-ld-framing/tests/frame-manifest.jsonld].each do |man| puts "load #{man}" g.load(man, unique_bnodes: true) end end puts "write" - RDF::NTriples::Writer.open("etc/manifests.nt", unique_bnodes: true, validate: false) {|w| w << graph} + RDF::NTriples::Writer.open("etc/manifests.nt", unique_bnodes: true, validate: false) { |w| w << graph } end # Presentation building namespace :presentation do desc "Clean presentation files" task :clean do - FileUtils.rm %w(compacted expanded framed).map {|f| "presentation/dbpedia/#{f}.jsonld"} + FileUtils.rm %w[compacted expanded framed].map { |f| "presentation/dbpedia/#{f}.jsonld" } end desc "Build presentation files" - task build: %w( + task build: %w[ presentation/dbpedia/expanded.jsonld presentation/dbpedia/compacted.jsonld presentation/dbpedia/framed.jsonld - ) + ] desc "Build expanded example" - file "presentation/dbpedia/expanded.jsonld" => %w( + file "presentation/dbpedia/expanded.jsonld" => %w[ presentation/dbpedia/orig.jsonld - presentation/dbpedia/expanded-context.jsonld) do - system(%w( - script/parse - --expand presentation/dbpedia/orig.jsonld - --context presentation/dbpedia/expanded-context.jsonld - -o presentation/dbpedia/expanded.jsonld).join(" ")) + presentation/dbpedia/expanded-context.jsonld + ] do + system(%w[ + script/parse + --expand presentation/dbpedia/orig.jsonld + --context presentation/dbpedia/expanded-context.jsonld + -o presentation/dbpedia/expanded.jsonld + ].join(" ")) end desc "Build compacted example" - file "presentation/dbpedia/compacted.jsonld" => %w( + file "presentation/dbpedia/compacted.jsonld" => %w[ presentation/dbpedia/expanded.jsonld - presentation/dbpedia/compact-context.jsonld) do - system(%w( - script/parse - --compact presentation/dbpedia/expanded.jsonld - --context presentation/dbpedia/compact-context.jsonld - -o presentation/dbpedia/compacted.jsonld).join(" ")) + presentation/dbpedia/compact-context.jsonld + ] do + system(%w[ + script/parse + --compact presentation/dbpedia/expanded.jsonld + --context presentation/dbpedia/compact-context.jsonld + -o presentation/dbpedia/compacted.jsonld + ].join(" ")) end desc "Build framed example" - file "presentation/dbpedia/framed.jsonld" => %w( + file "presentation/dbpedia/framed.jsonld" => %w[ presentation/dbpedia/expanded.jsonld - presentation/dbpedia/frame.jsonld) do - system(%w( - script/parse - --frame presentation/dbpedia/frame.jsonld - presentation/dbpedia/expanded.jsonld - -o presentation/dbpedia/framed.jsonld).join(" ")) + presentation/dbpedia/frame.jsonld + ] do + system(%w[ + script/parse + --frame presentation/dbpedia/frame.jsonld + presentation/dbpedia/expanded.jsonld + -o presentation/dbpedia/framed.jsonld + ].join(" ")) end end diff --git a/json-ld.gemspec b/json-ld.gemspec index 2e92c469..86462492 100755 --- a/json-ld.gemspec +++ b/json-ld.gemspec @@ -1,47 +1,44 @@ #!/usr/bin/env ruby -rubygems -# -*- encoding: utf-8 -*- +# frozen_string_literal: true is_java = RUBY_PLATFORM == 'java' Gem::Specification.new do |gem| gem.version = File.read('VERSION').chomp - gem.date = File.mtime('VERSION').strftime('%Y-%m-%d') gem.name = "json-ld" gem.homepage = "https://github.com/ruby-rdf/json-ld" gem.license = 'Unlicense' gem.summary = "JSON-LD reader/writer for Ruby." gem.description = "JSON::LD parses and serializes JSON-LD into RDF and implements expansion, compaction and framing API interfaces for the Ruby RDF.rb library suite." - gem.metadata = { + gem.metadata = { "documentation_uri" => "https://ruby-rdf.github.io/json-ld", - "bug_tracker_uri" => "https://github.com/ruby-rdf/json-ld/issues", - "homepage_uri" => "https://github.com/ruby-rdf/json-ld", - "mailing_list_uri" => "https://lists.w3.org/Archives/Public/public-rdf-ruby/", - "source_code_uri" => "https://github.com/ruby-rdf/json-ld", + "bug_tracker_uri" => "https://github.com/ruby-rdf/json-ld/issues", + "homepage_uri" => "https://github.com/ruby-rdf/json-ld", + "mailing_list_uri" => "https://lists.w3.org/Archives/Public/public-rdf-ruby/", + "source_code_uri" => "https://github.com/ruby-rdf/json-ld", + 'rubygems_mfa_required' => 'true' } gem.authors = ['Gregg Kellogg'] gem.email = 'public-linked-json@w3.org' gem.platform = Gem::Platform::RUBY - gem.files = %w(AUTHORS README.md UNLICENSE VERSION) + Dir.glob('lib/**/*.rb') - gem.bindir = %q(bin) - gem.executables = %w(jsonld) - gem.require_paths = %w(lib) - gem.test_files = Dir.glob('spec/**/*.rb') + Dir.glob('spec/test-files/*') + gem.files = %w[AUTHORS README.md UNLICENSE VERSION] + Dir.glob('lib/**/*.rb') + gem.bindir = 'bin' + gem.executables = %w[jsonld] + gem.require_paths = %w[lib] gem.required_ruby_version = '>= 2.6' gem.requirements = [] - gem.add_runtime_dependency 'rdf', '~> 3.2', '>= 3.2.10' - gem.add_runtime_dependency 'multi_json', '~> 1.15' - gem.add_runtime_dependency 'link_header', '~> 0.0', '>= 0.0.8' + gem.add_runtime_dependency 'htmlentities', '~> 4.3' gem.add_runtime_dependency 'json-canonicalization', '~> 0.3' - gem.add_runtime_dependency 'htmlentities', '~> 4.3' + gem.add_runtime_dependency 'link_header', '~> 0.0', '>= 0.0.8' + gem.add_runtime_dependency 'multi_json', '~> 1.15' gem.add_runtime_dependency "rack", '>= 2.2', '< 4' - gem.add_development_dependency 'sinatra-linkeddata','~> 3.2' + gem.add_runtime_dependency 'rdf', '~> 3.2', '>= 3.2.10' gem.add_development_dependency 'jsonlint', '~> 0.4' unless is_java - gem.add_development_dependency 'oj', '~> 3.14' unless is_java - gem.add_development_dependency 'yajl-ruby', '~> 1.4' unless is_java + gem.add_development_dependency 'oj', '~> 3.14' unless is_java gem.add_development_dependency 'rack-test', '>= 1.1', '< 3' gem.add_development_dependency 'rdf-isomorphic', '~> 3.2' gem.add_development_dependency 'rdf-spec', '~> 3.2' @@ -51,7 +48,9 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'rdf-xsd', '~> 3.2' gem.add_development_dependency 'rspec', '~> 3.12' gem.add_development_dependency 'rspec-its', '~> 1.3' - gem.add_development_dependency 'yard' , '~> 0.9' + gem.add_development_dependency 'sinatra-linkeddata', '~> 3.2' + gem.add_development_dependency 'yajl-ruby', '~> 1.4' unless is_java + gem.add_development_dependency 'yard', '~> 0.9' - gem.post_install_message = nil + gem.post_install_message = nil end diff --git a/lib/json/ld/context.rb b/lib/json/ld/context.rb index 7ff25c8f..8a4c58b5 100644 --- a/lib/json/ld/context.rb +++ b/lib/json/ld/context.rb @@ -1544,10 +1544,10 @@ def compact_iri(iri, base: nil, reverse: false, value: nil, vocab: nil) candidates = [] term_definitions.each do |term, td| - next if td.nil? || td.id.nil? || td.id == iri || !iri.start_with?(td.id) - # Skip term if `@prefix` is not true in term definition - next unless td.prefix? + next unless td&.prefix? + + next if td&.id.nil? || td.id == iri || !td.match_iri?(iri) suffix = iri[td.id.length..] ciri = "#{term}:#{suffix}" @@ -1572,7 +1572,7 @@ def compact_iri(iri, base: nil, reverse: false, value: nil, vocab: nil) # If iri could be confused with a compact IRI using a term in this context, signal an error term_definitions.each do |term, td| - next unless iri.to_s.start_with?("#{term}:") && td.prefix? + next unless td.prefix? && td.match_compact_iri?(iri) raise JSON::LD::JsonLdError::IRIConfusedWithPrefix, "Absolute IRI '#{iri}' confused with prefix '#{term}'" end @@ -2204,6 +2204,22 @@ def protected? !!@protected end + # Returns true if the term matches a IRI + # + # @param iri [String] the IRI + # @return [Boolean] + def match_iri?(iri) + iri.start_with?(id) + end + + # Returns true if the term matches a compact IRI + # + # @param iri [String] the compact IRI + # @return [Boolean] + def match_compact_iri?(iri) + iri.start_with?(prefix_colon) + end + # Set container mapping, from an array which may include @set def container_mapping=(mapping) mapping = case mapping @@ -2328,6 +2344,12 @@ def inspect v << "has-context" unless context.nil? v.join(" ") + "]" end + + private + + def prefix_colon + @prefix_colon ||= "#{term}:".freeze + end end end end diff --git a/lib/json/ld/flatten.rb b/lib/json/ld/flatten.rb index e74f3610..0eeb40f9 100644 --- a/lib/json/ld/flatten.rb +++ b/lib/json/ld/flatten.rb @@ -255,9 +255,9 @@ def rename_bnodes(node) when Array node.map { |n| rename_bnodes(n) } when Hash - node.inject({}) do |memo, (k, v)| + node.each_with_object({}) do |(k, v), memo| v = namer.get_name(v) if k == '@id' && v.is_a?(String) && blank_node?(v) - memo.merge(k => rename_bnodes(v)) + memo[k] = rename_bnodes(v) end else node diff --git a/lib/json/ld/frame.rb b/lib/json/ld/frame.rb index dc137fcc..1c42100f 100644 --- a/lib/json/ld/frame.rb +++ b/lib/json/ld/frame.rb @@ -273,15 +273,14 @@ def prune_bnodes(input, bnodes_to_clear) def cleanup_preserve(input) case input when Array - # If, after replacement, an array contains only the value null remove the value, leaving an empty array. - input.map { |o| cleanup_preserve(o) } + input.map! { |o| cleanup_preserve(o) } when Hash if input.key?('@preserve') # Replace with the content of `@preserve` cleanup_preserve(input['@preserve'].first) else - input.inject({}) do |memo, (k, v)| - memo.merge(k => cleanup_preserve(v)) + input.transform_values do |v| + cleanup_preserve(v) end end else @@ -298,10 +297,10 @@ def cleanup_null(input) case input when Array # If, after replacement, an array contains only the value null remove the value, leaving an empty array. - input.map { |o| cleanup_null(o) }.compact + input.map! { |o| cleanup_null(o) }.compact when Hash - input.inject({}) do |memo, (k, v)| - memo.merge(k => cleanup_null(v)) + input.transform_values do |v| + cleanup_null(v) end when '@null' # If the value from the key-pair is @null, replace the value with null diff --git a/spec/api_spec.rb b/spec/api_spec.rb index 62690226..6da625be 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -1,37 +1,38 @@ +# frozen_string_literal: true -# coding: utf-8 require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} - before {JSON::LD::Context::PRELOADED.clear} + let(:logger) { RDF::Spec.logger } + + before { JSON::LD::Context::PRELOADED.clear } describe "#initialize" do context "with string input" do let(:context) do - JSON::LD::API::RemoteDocument.new(%q({ + JSON::LD::API::RemoteDocument.new('{ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"}, "avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"} } - }), + }', documentUrl: "http://example.com/context", - contentType: 'application/ld+json' - ) + contentType: 'application/ld+json') end let(:remote_doc) do - JSON::LD::API::RemoteDocument.new(%q({"@id": "", "name": "foo"}), + JSON::LD::API::RemoteDocument.new('{"@id": "", "name": "foo"}', documentUrl: "http://example.com/foo", contentType: 'application/ld+json', - contextUrl: "http://example.com/context" - ) + contextUrl: "http://example.com/context") end it "loads document with loader and loads context" do - expect(described_class).to receive(:documentLoader).with("http://example.com/foo", anything).and_yield(remote_doc) - expect(described_class).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(context) + expect(described_class).to receive(:documentLoader).with("http://example.com/foo", + anything).and_yield(remote_doc) + expect(described_class).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(context) described_class.new("http://example.com/foo", nil) end end @@ -39,12 +40,15 @@ context "when validating", pending: ("JRuby support for jsonlint" if RUBY_ENGINE == "jruby") do it "detects invalid JSON" do - expect {described_class.new(StringIO.new(%({"a": "b", "a": "c"})), nil, validate: true)}.to raise_error(JSON::LD::JsonLdError::LoadingDocumentFailed) + expect do + described_class.new(StringIO.new(%({"a": "b", "a": "c"})), nil, + validate: true) + end.to raise_error(JSON::LD::JsonLdError::LoadingDocumentFailed) end end context "Test Files" do - %i(oj json_gem ok_json yajl).each do |adapter| + %i[oj json_gem ok_json yajl].each do |adapter| context "with MultiJson adapter #{adapter.inspect}" do Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'test-files/*-input.*'))) do |filename| test = File.basename(filename).sub(/-input\..*$/, '') @@ -54,43 +58,44 @@ context = filename.sub(/-input\..*$/, '-context.jsonld') expanded = filename.sub(/-input\..*$/, '-expanded.jsonld') ttl = filename.sub(/-input\..*$/, '-rdf.ttl') - - context test, skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w(oj yajl).include?(adapter.to_s)) do + + context test, + skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w[oj yajl].include?(adapter.to_s)) do around do |example| @file = File.open(filename) case filename when /.jsonld$/ - @file.define_singleton_method(:content_type) {'application/ld+json'} + @file.define_singleton_method(:content_type) { 'application/ld+json' } end if context @ctx_io = File.open(context) case context when /.jsonld$/ - @ctx_io.define_singleton_method(:content_type) {'application/ld+json'} + @ctx_io.define_singleton_method(:content_type) { 'application/ld+json' } end end example.run @file.close - @ctx_io.close if @ctx_io + @ctx_io&.close end if File.exist?(expanded) it "expands" do - options = {logger: logger, adapter: adapter} + options = { logger: logger, adapter: adapter } options[:expandContext] = @ctx_io if context jld = described_class.expand(@file, **options) expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger) end it "expands with serializer" do - options = {logger: logger, adapter: adapter} + options = { logger: logger, adapter: adapter } options[:expandContext] = @ctx_io if context - jld = described_class.expand(@file, serializer: JSON::LD::API.method(:serializer), **options) + jld = described_class.expand(@file, serializer: described_class.method(:serializer), **options) expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger) + expect(JSON.parse(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger) end end - + if File.exist?(compacted) && File.exist?(context) it "compacts" do jld = described_class.compact(@file, @ctx_io, adapter: adapter, logger: logger) @@ -98,12 +103,13 @@ end it "compacts with serializer" do - jld = described_class.compact(@file, @ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + jld = described_class.compact(@file, @ctx_io, serializer: described_class.method(:serializer), + adapter: adapter, logger: logger) expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger) + expect(JSON.parse(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger) end end - + if File.exist?(framed) && File.exist?(frame) it "frames" do File.open(frame) do |frame_io| @@ -114,16 +120,20 @@ it "frames with serializer" do File.open(frame) do |frame_io| - jld = described_class.frame(@file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger) + jld = described_class.frame(@file, frame_io, serializer: described_class.method(:serializer), + adapter: adapter, logger: logger) expect(jld).to be_a(String) - expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger) + expect(JSON.parse(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger) end end end - it "toRdf" do - expect(RDF::Repository.load(filename, format: :jsonld, adapter: adapter, logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger) - end if File.exist?(ttl) + if File.exist?(ttl) + it "toRdf" do + expect(RDF::Repository.load(filename, format: :jsonld, adapter: adapter, + logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger) + end + end end end end diff --git a/spec/compact_spec.rb b/spec/compact_spec.rb index 717ce72c..e89382e2 100644 --- a/spec/compact_spec.rb +++ b/spec/compact_spec.rb @@ -1,8 +1,9 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } describe ".compact" do { @@ -87,7 +88,7 @@ "b": "2012-01-04" }) }, - "@list coercion": { + '@list coercion': { input: %({ "http://example.com/b": {"@list": ["c", "d"]} }), @@ -156,7 +157,7 @@ output: %({ "@id": "http://example.com/", "@type": "#{RDF::RDFS.Resource}" - }), + }) }, "@type with array @id" => { input: %({ @@ -167,7 +168,7 @@ output: %({ "@id": "http://example.com/", "@type": "#{RDF::RDFS.Resource}" - }), + }) }, "default language" => { input: %({ @@ -206,9 +207,9 @@ }, "term5": [ "v5", "plain literal" ] }) - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end context "keyword aliasing" do @@ -225,7 +226,7 @@ "@type": "#{RDF::RDFS.Resource}" }) }, - "@type": { + '@type': { input: %({ "@type": "http://www.w3.org/2000/01/rdf-schema#Resource", "http://example.org/foo": {"@value": "bar", "@type": "http://example.com/type"} @@ -237,7 +238,7 @@ "http://example.org/foo": {"@value": "bar", "type": "http://example.com/type"} }) }, - "@type with @container: @set": { + '@type with @container: @set': { input: %({ "@type": "http://www.w3.org/2000/01/rdf-schema#Resource", "http://example.org/foo": {"@value": "bar", "@type": "http://example.com/type"} @@ -289,9 +290,9 @@ "@context": {"list": "@list"}, "http://example.org/foo": {"list": ["bar"]} }) - }, + } }.each do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -402,9 +403,9 @@ }, "http://example/t": {"@id": "http://example/id"} }) - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -465,9 +466,9 @@ }), base: "http://example.org/", processingMode: 'json-ld-1.1' - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -532,7 +533,7 @@ }) } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -553,27 +554,30 @@ }) } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end context "context as reference" do let(:remote_doc) do JSON::LD::API::RemoteDocument.new( - %q({"@context": {"b": "http://example.com/b"}}), - documentUrl: "http://example.com/context") + '{"@context": {"b": "http://example.com/b"}}', + documentUrl: "http://example.com/context" + ) end + it "uses referenced context" do JSON::LD::Context.instance_variable_set(:@cache, nil) - input = ::JSON.parse %({ + input = JSON.parse %({ "http://example.com/b": "c" }) - expected = ::JSON.parse %({ + expected = JSON.parse %({ "@context": "http://example.com/context", "b": "c" }) - allow(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) - jld = JSON::LD::API.compact(input, "http://example.com/context", logger: logger, validate: true) + allow(described_class).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) + jld = described_class.compact(input, "http://example.com/context", logger: logger, validate: true) expect(jld).to produce_jsonld(expected, logger) end end @@ -630,7 +634,7 @@ output: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [[]] - }), + }) }, "coerced @list containing a list" => { input: %([{ @@ -642,7 +646,7 @@ output: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["baz"]] - }), + }) }, "coerced @list containing an deep list" => { input: %([{ @@ -654,7 +658,7 @@ output: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [[["baz"]]] - }), + }) }, "coerced @list containing multiple lists" => { input: %([{ @@ -669,7 +673,7 @@ output: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["a"], ["b"]] - }), + }) }, "coerced @list containing mixed list values" => { input: %([{ @@ -684,16 +688,16 @@ output: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["a"], "b"] - }), - }, + }) + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end context "with @type: @json" do { - "true": { + true => { output: %({ "@context": { "@version": 1.1, @@ -701,11 +705,11 @@ }, "e": true }), - input:%( [{ + input: %( [{ "http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}] - }]), + }]) }, - "false": { + false => { output: %({ "@context": { "@version": 1.1, @@ -715,9 +719,9 @@ }), input: %([{ "http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}] - }]), + }]) }, - "double": { + double: { output: %({ "@context": { "@version": 1.1, @@ -727,9 +731,9 @@ }), input: %([{ "http://example.org/vocab#double": [{"@value": 1.23, "@type": "@json"}] - }]), + }]) }, - "double-zero": { + 'double-zero': { output: %({ "@context": { "@version": 1.1, @@ -739,9 +743,9 @@ }), input: %([{ "http://example.org/vocab#double": [{"@value": 0.0e0, "@type": "@json"}] - }]), + }]) }, - "integer": { + integer: { output: %({ "@context": { "@version": 1.1, @@ -751,9 +755,9 @@ }), input: %([{ "http://example.org/vocab#integer": [{"@value": 123, "@type": "@json"}] - }]), + }]) }, - "string": { + string: { input: %([{ "http://example.org/vocab#string": [{ "@value": "string", @@ -768,7 +772,7 @@ "e": "string" }) }, - "null": { + null: { input: %([{ "http://example.org/vocab#null": [{ "@value": null, @@ -783,7 +787,7 @@ "e": null }) }, - "object": { + object: { output: %({ "@context": { "@version": 1.1, @@ -793,9 +797,9 @@ }), input: %([{ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] - }]), + }]) }, - "array": { + array: { output: %({ "@context": { "@version": 1.1, @@ -805,18 +809,18 @@ }), input: %([{ "http://example.org/vocab#array": [{"@value": [{"foo": "bar"}], "@type": "@json"}] - }]), + }]) }, - "Already expanded object": { + 'Already expanded object': { output: %({ "@context": {"@version": 1.1}, "http://example.org/vocab#object": {"@value": {"foo": "bar"}, "@type": "@json"} }), input: %([{ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] - }]), + }]) }, - "Already expanded object with aliased keys": { + 'Already expanded object with aliased keys': { output: %({ "@context": {"@version": 1.1, "value": "@value", "type": "@type", "json": "@json"}, "http://example.org/vocab#object": {"value": {"foo": "bar"}, "type": "json"} @@ -824,9 +828,9 @@ input: %([{ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] }]) - }, + } }.each do |title, params| - it(title) {run_compact(processingMode: 'json-ld-1.1', **params)} + it(title) { run_compact(processingMode: 'json-ld-1.1', **params) } end end @@ -954,7 +958,7 @@ }), processingMode: 'json-ld-1.1' }, - "issue-514": { + 'issue-514': { input: %({ "http://example.org/ns/prop": [{ "@id": "http://example.org/ns/bar", @@ -989,7 +993,7 @@ } }) }, - "issue-514b": { + 'issue-514b': { input: %({ "http://example.org/ns/prop": [{ "@id": "http://example.org/ns/bar", @@ -1023,14 +1027,14 @@ "bar": { "@id": "ex:bar"} } }) - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end context "@index: property" do { - "property-valued index indexes property value, instead of property (value)": { + 'property-valued index indexes property value, instead of property (value)': { output: %({ "@context": { "@version": 1.1, @@ -1053,7 +1057,7 @@ ] }]) }, - "property-valued index indexes property value, instead of @index (multiple values)": { + 'property-valued index indexes property value, instead of @index (multiple values)': { output: %({ "@context": { "@version": 1.1, @@ -1079,7 +1083,7 @@ ] }]) }, - "property-valued index extracts property value, instead of @index (node)": { + 'property-valued index extracts property value, instead of @index (node)': { output: %({ "@context": { "@version": 1.1, @@ -1106,7 +1110,7 @@ ] }]) }, - "property-valued index indexes property value, instead of property (multimple nodes)": { + 'property-valued index indexes property value, instead of property (multimple nodes)': { output: %({ "@context": { "@version": 1.1, @@ -1133,7 +1137,7 @@ ] }]) }, - "property-valued index indexes using @none if no property value exists": { + 'property-valued index indexes using @none if no property value exists': { output: %({ "@context": { "@version": 1.1, @@ -1155,7 +1159,7 @@ ] }]) }, - "property-valued index indexes using @none if no property value does not compact to string": { + 'property-valued index indexes using @none if no property value does not compact to string': { output: %({ "@context": { "@version": 1.1, @@ -1182,7 +1186,7 @@ }]) } }.each do |title, params| - it(title) {run_compact(**params)} + it(title) { run_compact(**params) } end end end @@ -1276,7 +1280,7 @@ }), processingMode: "json-ld-1.1" }, - "simple map with term direction": { + 'simple map with term direction': { input: %([ { "@id": "http://example.com/queen", @@ -1316,7 +1320,7 @@ }), processingMode: "json-ld-1.1" }, - "simple map with overriding term direction": { + 'simple map with overriding term direction': { input: %([ { "@id": "http://example.com/queen", @@ -1358,7 +1362,7 @@ }), processingMode: "json-ld-1.1" }, - "simple map with overriding null direction": { + 'simple map with overriding null direction': { input: %([ { "@id": "http://example.com/queen", @@ -1400,7 +1404,7 @@ }), processingMode: "json-ld-1.1" }, - "simple map with mismatching term direction": { + 'simple map with mismatching term direction': { input: %([ { "@id": "http://example.com/queen", @@ -1442,9 +1446,9 @@ ] }), processingMode: "json-ld-1.1" - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -1470,7 +1474,7 @@ "http://example.org/foo": {"label": "Object with @id "}, "_:bar": {"label": "Object with @id _:bar"} } - }), + }) }, "Indexes to object already having an @id" => { input: %([{ @@ -1492,7 +1496,7 @@ "_:foo": {"label": "Object with @id _:bar"}, "http://example.org/bar": {"label": "Object with @id "} } - }), + }) }, "Indexes to object using compact IRI @id" => { input: %([{ @@ -1561,9 +1565,9 @@ "none": {"label": "Object with no @id"} } }) - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -1712,9 +1716,9 @@ "none": {"label": "Object with no @id"} } }) - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -1888,7 +1892,7 @@ }) } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end context "+ @index" do @@ -1986,9 +1990,9 @@ "@graph": {"value": "x"} } }) - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -2150,16 +2154,16 @@ "none" : {"value": "x"} } }) - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end end context "@included" do { - "Basic Included array": { + 'Basic Included array': { output: %({ "@context": { "@version": 1.1, @@ -2178,7 +2182,7 @@ }] }]) }, - "Basic Included object": { + 'Basic Included object': { output: %({ "@context": { "@version": 1.1, @@ -2196,7 +2200,7 @@ }] }]) }, - "Multiple properties mapping to @included are folded together": { + 'Multiple properties mapping to @included are folded together': { output: %({ "@context": { "@version": 1.1, @@ -2216,7 +2220,7 @@ ] }]) }, - "Included containing @included": { + 'Included containing @included': { output: %({ "@context": { "@version": 1.1, @@ -2240,7 +2244,7 @@ }] }]) }, - "Property value with @included": { + 'Property value with @included': { output: %({ "@context": { "@version": 1.1, @@ -2261,9 +2265,9 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -2374,7 +2378,7 @@ "nestedlist": { "list": ["a", "b"] } - }), + }) }, "Nested @container: @index" => { input: %([{ @@ -2400,7 +2404,7 @@ "B": "b" } } - }), + }) }, "Nested @container: @language" => { input: %([{ @@ -2512,9 +2516,9 @@ "term": {"@id": "http://example/foo", "@nest": "unknown"} }), exception: JSON::LD::JsonLdError::InvalidNestValue - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -2533,9 +2537,9 @@ {"ex:bar": "bar"} ] }) - }, + } }.each_pair do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end @@ -2579,7 +2583,7 @@ "foo": { "bar": "http://example/baz" } - }), + }) }, "property and value with different terms mapping to the same expanded property" => { input: %([ @@ -2603,7 +2607,7 @@ "foo": { "Bar": "baz" } - }), + }) }, "deep @context affects nested nodes" => { input: %([ @@ -2629,7 +2633,7 @@ "baz": "buzz" } } - }), + }) }, "scoped context layers on intemediate contexts" => { input: %([{ @@ -2659,7 +2663,7 @@ "http://example.com/c": "C in example.com" }, "c": "C in example" - }), + }) }, "Raises InvalidTermDefinition if processingMode is 1.0" => { input: %([{ @@ -2673,7 +2677,7 @@ validate: true, exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "Scoped on id map": { + 'Scoped on id map': { output: %({ "@context": { "@version": 1.1, @@ -2721,9 +2725,9 @@ "http://schema.org/wordCount": [{"@value": 1204}] }] }]) - }, + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -2771,7 +2775,7 @@ "bar": {"@type": "http://www.w3.org/2001/XMLSchema#string"} }, "a": {"@type": "Foo", "bar": "http://example/baz"} - }), + }) }, "alias of @type" => { input: %([ @@ -2794,7 +2798,7 @@ "Foo": {"@context": {"bar": "http://example.org/bar"}} }, "a": {"type": "Foo", "bar": "baz"} - }), + }) }, "deep @context does not affect nested nodes" => { input: %([ @@ -2816,7 +2820,7 @@ }, "@type": "Foo", "bar": {"baz": {"@id": "http://example/buzz"}} - }), + }) }, "scoped context layers on intemediate contexts" => { input: %([{ @@ -2842,7 +2846,7 @@ "http://example.com/a": "A in example.com" }, "c": "C in example" - }), + }) }, "orders lexicographically" => { input: %([{ @@ -2864,7 +2868,7 @@ }, "@type": ["t2", "t1"], "foo": "urn:bar" - }), + }) }, "with @container: @type" => { input: %([{ @@ -2937,10 +2941,10 @@ "@type": "Foo", "bar": {"@id": "http://example.org/baz"} } - }), - }, + }) + } }.each_pair do |title, params| - it(title) {run_compact({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_compact({ processingMode: "json-ld-1.1" }.merge(params)) } end end @@ -3035,16 +3039,16 @@ "@context": {"@base": "http://example.org/foo/", "@vocab": ""}, "bar": "term" }) - }, + } }.each do |title, params| - it(title) {run_compact(params)} + it(title) { run_compact(params) } end end end context "html" do { - "Compacts embedded JSON-LD script element": { + 'Compacts embedded JSON-LD script element': { input: %( @@ -3066,7 +3070,7 @@ "foo": ["bar"] }) }, - "Compacts first script element": { + 'Compacts first script element': { input: %( @@ -3097,7 +3101,7 @@ "foo": ["bar"] }) }, - "Compacts targeted script element": { + 'Compacts targeted script element': { input: %( @@ -3130,7 +3134,7 @@ }), base: "http://example.org/doc#second" }, - "Compacts all script elements with extractAllScripts option": { + 'Compacts all script elements with extractAllScripts option': { input: %( @@ -3173,11 +3177,11 @@ ] }), extractAllScripts: true - }, + } }.each do |title, params| it(title) do params[:input] = StringIO.new(params[:input]) - params[:input].send(:define_singleton_method, :content_type) {"text/html"} + params[:input].send(:define_singleton_method, :content_type) { "text/html" } run_compact params.merge(validate: true) end end @@ -3185,7 +3189,7 @@ context "JSON-LD-star" do { - "subject-iii": { + 'subject-iii': { input: %([{ "@id": { "@id": "http://example/s1", @@ -3203,7 +3207,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-iib": { + 'subject-iib': { input: %([{ "@id": { "@id": "http://example/s1", @@ -3221,7 +3225,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-iil": { + 'subject-iil': { input: %([{ "@id": { "@id": "http://example/s1", @@ -3239,7 +3243,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bii": { + 'subject-bii': { input: %([{ "@id": { "@id": "_:s1", @@ -3257,7 +3261,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bib": { + 'subject-bib': { input: %([{ "@id": { "@id": "_:s1", @@ -3275,7 +3279,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bil": { + 'subject-bil': { input: %([{ "@id": { "@id": "_:s1", @@ -3293,7 +3297,7 @@ "ex:p": {"@id": "ex:o"} }) }, - "object-iii": { + 'object-iii': { input: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -3315,7 +3319,7 @@ } }) }, - "object-iib": { + 'object-iib': { input: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -3337,7 +3341,7 @@ } }) }, - "object-iil": { + 'object-iil': { input: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -3359,7 +3363,7 @@ } }) }, - "recursive-subject": { + 'recursive-subject': { input: %([{ "@id": { "@id": { @@ -3382,15 +3386,15 @@ }, "ex:p": {"@id": "ex:o"} }) - }, + } }.each do |name, params| - it(name) {run_compact(params.merge(rdfstar: true))} + it(name) { run_compact(params.merge(rdfstar: true)) } end end context "problem cases" do { - "issue json-ld-framing#64": { + 'issue json-ld-framing#64': { input: %({ "@context": { "@version": 1.1, @@ -3413,7 +3417,7 @@ "Production": { "@context": { "part": { - "@type": "@id", + "@type": "@id", "@container": "@set" } } @@ -3426,7 +3430,7 @@ "Production": { "@context": { "part": { - "@type": "@id", + "@type": "@id", "@container": "@set" } } @@ -3453,22 +3457,26 @@ end def run_compact(params) - input, output, context = params[:input], params[:output], params[:context] + input = params[:input] + output = params[:output] + context = params[:context] params[:base] ||= nil - context ||= output # Since it will have the context - input = ::JSON.parse(input) if input.is_a?(String) - output = ::JSON.parse(output) if output.is_a?(String) - context = ::JSON.parse(context) if context.is_a?(String) + context ||= output # Since it will have the context + input = JSON.parse(input) if input.is_a?(String) + output = JSON.parse(output) if output.is_a?(String) + context = JSON.parse(context) if context.is_a?(String) context = context['@context'] if context.key?('@context') pending params.fetch(:pending, "test implementation") unless input if params[:exception] - expect {JSON::LD::API.compact(input, context, logger: logger, **params)}.to raise_error(params[:exception]) + expect { JSON::LD::API.compact(input, context, logger: logger, **params) }.to raise_error(params[:exception]) else jld = nil if params[:write] - expect{jld = JSON::LD::API.compact(input, context, logger: logger, **params)}.to write(params[:write]).to(:error) + expect do + jld = JSON::LD::API.compact(input, context, logger: logger, **params) + end.to write(params[:write]).to(:error) else - expect{jld = JSON::LD::API.compact(input, context, logger: logger, **params)}.not_to write.to(:error) + expect { jld = JSON::LD::API.compact(input, context, logger: logger, **params) }.not_to write.to(:error) end expect(jld).to produce_jsonld(output, logger) diff --git a/spec/conneg_spec.rb b/spec/conneg_spec.rb index 8341f2f0..aecefce6 100644 --- a/spec/conneg_spec.rb +++ b/spec/conneg_spec.rb @@ -1,11 +1,12 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rack/linkeddata' require 'rack/test' describe JSON::LD::ContentNegotiation do - include ::Rack::Test::Methods - let(:logger) {RDF::Spec.logger} + include Rack::Test::Methods + let(:logger) { RDF::Spec.logger } let(:app) do described_class.new(double("Target Rack Application", :call => [200, {}, @results || "A String"])) @@ -13,9 +14,9 @@ describe "#parse_accept_header" do { - "application/n-triples, application/ld+json;q=0.5" => %w(application/ld+json), + "application/n-triples, application/ld+json;q=0.5" => %w[application/ld+json], "application/ld+json, application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted" => - %w(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted application/ld+json), + %w[application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted application/ld+json] }.each do |accept, content_types| it "returns #{content_types.inspect} given #{accept.inspect}" do expect(app.send(:parse_accept_header, accept)).to eq content_types @@ -39,17 +40,17 @@ end describe "#call" do - let(:schema_context) { - JSON::LD::API::RemoteDocument.new(%q({ + let(:schema_context) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "@vocab": "http://schema.org/", "id": "@id", "type": "@type" } - }), documentUrl: "http://schema.org") - } - let(:frame) { - JSON::LD::API::RemoteDocument.new(%q({ + }', documentUrl: "http://schema.org") + end + let(:frame) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" @@ -61,21 +62,23 @@ "@type": "ex:Chapter" } } - }), documentUrl: "http://conneg.example.com/frame") - } - let(:context) { - JSON::LD::API::RemoteDocument.new(%q({ + }', documentUrl: "http://conneg.example.com/frame") + end + let(:context) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" } - }), documentUrl: "http://conneg.example.com/context") - } + }', documentUrl: "http://conneg.example.com/context") + end - before(:each) do + before do allow(JSON::LD::API).to receive(:documentLoader).with("http://schema.org", any_args).and_yield(schema_context) - allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", any_args).and_yield(context) - allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", any_args).and_yield(frame) + allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", + any_args).and_yield(context) + allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", + any_args).and_yield(frame) end context "with text result" do @@ -86,7 +89,7 @@ end context "with object result" do - before(:each) do + before do @results = LIBRARY_INPUT end @@ -97,9 +100,9 @@ context "with Accept" do { - "application/n-triples" => "406 Not Acceptable (No appropriate combinaion of media-type and parameters found)\n", - "application/json" => LIBRARY_INPUT, - "application/ld+json" => LIBRARY_INPUT, + "application/n-triples" => "406 Not Acceptable (No appropriate combinaion of media-type and parameters found)\n", + "application/json" => LIBRARY_INPUT, + "application/ld+json" => LIBRARY_INPUT, %(application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded) => LIBRARY_EXPANDED, @@ -127,15 +130,15 @@ %(application/ld+json;profile="http://www.w3.org/ns/json-ld#framed http://www.w3.org/ns/json-ld#compacted") => "406 Not Acceptable (framed profile without a frame)\n", %(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#framed") => - "406 Not Acceptable (framed profile without a frame)\n", + "406 Not Acceptable (framed profile without a frame)\n" }.each do |accepts, result| context accepts do - before(:each) do - get '/', {}, {"HTTP_ACCEPT" => accepts} + before do + get '/', {}, { "HTTP_ACCEPT" => accepts } end it "status" do - expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)} + expect(last_response.status).to satisfy("be 200 or 406") { |x| [200, 406].include?(x) } end it "sets content type" do @@ -185,15 +188,15 @@ accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed), link: %( rel="http://www.w3.org/ns/json-ld#context"), result: "406 Not Acceptable (framed profile without a frame)\n" - }, + } }.each do |name, params| context name do - before(:each) do - get '/', {}, {"HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link]} + before do + get '/', {}, { "HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link] } end it "status" do - expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)} + expect(last_response.status).to satisfy("be 200 or 406") { |x| [200, 406].include?(x) } end it "sets content type" do @@ -215,8 +218,8 @@ end describe Rack::LinkedData::ContentNegotiation do - include ::Rack::Test::Methods - let(:logger) {RDF::Spec.logger} + include Rack::Test::Methods + let(:logger) { RDF::Spec.logger } let(:app) do graph = RDF::NTriples::Reader.new(%( @@ -230,21 +233,21 @@ "The Introduction" . "An introductory chapter on The Republic." . )) - Rack::LinkedData::ContentNegotiation.new(double("Target Rack Application", :call => [200, {}, graph]), {}) + described_class.new(double("Target Rack Application", :call => [200, {}, graph]), {}) end describe "#call" do - let(:schema_context) { - JSON::LD::API::RemoteDocument.new(%q({ + let(:schema_context) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "@vocab": "http://schema.org/", "id": "@id", "type": "@type" } - }), documentUrl: "http://schema.org") - } - let(:frame) { - JSON::LD::API::RemoteDocument.new(%q({ + }', documentUrl: "http://schema.org") + end + let(:frame) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" @@ -256,26 +259,28 @@ "@type": "ex:Chapter" } } - }), documentUrl: "http://conneg.example.com/frame") - } - let(:context) { - JSON::LD::API::RemoteDocument.new(%q({ + }', documentUrl: "http://conneg.example.com/frame") + end + let(:context) do + JSON::LD::API::RemoteDocument.new('{ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" } - }), documentUrl: "http://conneg.example.com/context") - } + }', documentUrl: "http://conneg.example.com/context") + end - before(:each) do + before do allow(JSON::LD::API).to receive(:documentLoader).with("http://schema.org", any_args).and_yield(schema_context) - allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", any_args).and_yield(context) - allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", any_args).and_yield(frame) + allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", + any_args).and_yield(context) + allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", + any_args).and_yield(frame) end { - "application/json" => LIBRARY_FLATTENED_EXPANDED, - "application/ld+json" => LIBRARY_FLATTENED_EXPANDED, + "application/json" => LIBRARY_FLATTENED_EXPANDED, + "application/ld+json" => LIBRARY_FLATTENED_EXPANDED, %(application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded) => LIBRARY_FLATTENED_EXPANDED, @@ -292,16 +297,16 @@ %(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted") => LIBRARY_FLATTENED_COMPACTED_DEFAULT, %(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#flattened") => - LIBRARY_FLATTENED_COMPACTED_DEFAULT, + LIBRARY_FLATTENED_COMPACTED_DEFAULT }.each do |accepts, result| context accepts do - before(:each) do - get '/', {}, {"HTTP_ACCEPT" => accepts} + before do + get '/', {}, { "HTTP_ACCEPT" => accepts } end it "status" do - expect(last_response.status).to satisfy("200 or 406") {|x| [200, 406].include?(x)} + expect(last_response.status).to satisfy("200 or 406") { |x| [200, 406].include?(x) } end it "sets content type" do @@ -344,15 +349,15 @@ accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed), link: %( rel="http://www.w3.org/ns/json-ld#frame"), result: LIBRARY_FRAMED - }, + } }.each do |name, params| context name do - before(:each) do - get '/', {}, {"HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link]} + before do + get '/', {}, { "HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link] } end it "status" do - expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)} + expect(last_response.status).to satisfy("be 200 or 406") { |x| [200, 406].include?(x) } end it "sets content type" do diff --git a/spec/context_spec.rb b/spec/context_spec.rb index 01bade21..9d12519e 100644 --- a/spec/context_spec.rb +++ b/spec/context_spec.rb @@ -1,48 +1,52 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/xsd' require 'rdf/spec/reader' # Add for testing -class JSON::LD::Context - # Retrieve type mappings - def coercions - term_definitions.inject({}) do |memo, (t,td)| - memo[t] = td.type_mapping - memo - end - end +module JSON + module LD + class Context + # Retrieve type mappings + def coercions + term_definitions.transform_values(&:type_mapping) + end - def containers - term_definitions.inject({}) do |memo, (t,td)| - memo[t] = td.container_mapping - memo + def containers + term_definitions.transform_values(&:container_mapping) + end end end end describe JSON::LD::Context do - let(:logger) {RDF::Spec.logger} - let(:context) {JSON::LD::Context.new(logger: logger, validate: true, processingMode: "json-ld-1.1", compactToRelative: true)} + subject { context } + + let(:logger) { RDF::Spec.logger } + let(:context) do + described_class.new(logger: logger, validate: true, processingMode: "json-ld-1.1", compactToRelative: true) + end let(:remote_doc) do - JSON::LD::API::RemoteDocument.new(%q({ + JSON::LD::API::RemoteDocument.new('{ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"}, "avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"} } - }), - documentUrl: "http://example.com/context", - contentType: "application/ld+json") + }', + documentUrl: "http://example.com/context", + contentType: "application/ld+json") end - subject {context} describe ".parse" do - let(:ctx) {[ - {"foo" => "http://example.com/foo"}, - {"bar" => "foo"} - ]} + let(:ctx) do + [ + { "foo" => "http://example.com/foo" }, + { "bar" => "foo" } + ] + end it "merges definitions from each context" do ec = described_class.parse(ctx) @@ -55,27 +59,30 @@ def containers describe "#parse" do context "remote" do - it "fails given a missing remote @context" do - JSON::LD::Context.instance_variable_set(:@cache, nil) - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_raise(IOError) - expect {subject.parse("http://example.com/context")}.to raise_error(JSON::LD::JsonLdError::LoadingRemoteContextFailed, %r{http://example.com/context}) + described_class.instance_variable_set(:@cache, nil) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_raise(IOError) + expect do + subject.parse("http://example.com/context") + end.to raise_error(JSON::LD::JsonLdError::LoadingRemoteContextFailed, %r{http://example.com/context}) end it "creates mappings" do - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) ec = subject.parse("http://example.com/context") expect(ec.send(:mappings)).to produce({ - "xsd" => "http://www.w3.org/2001/XMLSchema#", - "name" => "http://xmlns.com/foaf/0.1/name", + "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" + "avatar" => "http://xmlns.com/foaf/0.1/avatar" }, logger) end it "retrieves and parses a remote context document in HTML using the context profile" do remote_doc = - JSON::LD::API::RemoteDocument.new(%q( + JSON::LD::API::RemoteDocument.new(+' - ), + ', documentUrl: "http://example.com/context", contentType: "text/html") - JSON::LD::Context.instance_variable_set(:@cache, nil) - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) + described_class.instance_variable_set(:@cache, nil) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) ec = subject.parse("http://example.com/context") expect(ec.send(:mappings)).to produce({ - "xsd" => "http://www.w3.org/2001/XMLSchema#", - "name" => "http://xmlns.com/foaf/0.1/name", + "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" + "avatar" => "http://xmlns.com/foaf/0.1/avatar" }, logger) end it "retrieves and parses a remote context document in HTML" do remote_doc = - JSON::LD::API::RemoteDocument.new(%q( + JSON::LD::API::RemoteDocument.new(+' - ), + ', documentUrl: "http://example.com/context", contentType: "text/html") - JSON::LD::Context.instance_variable_set(:@cache, nil) - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) + described_class.instance_variable_set(:@cache, nil) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) ec = subject.parse("http://example.com/context") expect(ec.send(:mappings)).to produce({ - "xsd" => "http://www.w3.org/2001/XMLSchema#", - "name" => "http://xmlns.com/foaf/0.1/name", + "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" + "avatar" => "http://xmlns.com/foaf/0.1/avatar" }, logger) end it "notes non-existing @context" do - expect {subject.parse(StringIO.new("{}"))}.to raise_error(JSON::LD::JsonLdError::InvalidRemoteContext) + expect { subject.parse(StringIO.new("{}")) }.to raise_error(JSON::LD::JsonLdError::InvalidRemoteContext) end it "parses a referenced context at a relative URI" do - JSON::LD::Context.instance_variable_set(:@cache, nil) + described_class.instance_variable_set(:@cache, nil) rd1 = JSON::LD::API::RemoteDocument.new(%({"@context": "context"}), base_uri: "http://example.com/c1") expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c1", anything).and_yield(rd1) - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) ec = subject.parse("http://example.com/c1") expect(ec.send(:mappings)).to produce({ - "xsd" => "http://www.w3.org/2001/XMLSchema#", - "name" => "http://xmlns.com/foaf/0.1/name", + "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" + "avatar" => "http://xmlns.com/foaf/0.1/avatar" }, logger) end context "remote with local mappings" do - let(:ctx) {["http://example.com/context", {"integer" => "xsd:integer"}]} - before {JSON::LD::Context.instance_variable_set(:@cache, nil)} + let(:ctx) { ["http://example.com/context", { "integer" => "xsd:integer" }] } + + before { described_class.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) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) 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", + "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" + "avatar" => "http://xmlns.com/foaf/0.1/avatar", + "integer" => "http://www.w3.org/2001/XMLSchema#integer" }, logger) end end context "pre-loaded remote" do - let(:ctx) {"http://example.com/preloaded"} - before(:all) { - JSON::LD::Context.add_preloaded("http://example.com/preloaded", - JSON::LD::Context.parse({'foo' => "http://example.com/"}) - ) - JSON::LD::Context.alias_preloaded("https://example.com/preloaded", "http://example.com/preloaded") - } - after(:all) {JSON::LD::Context.instance_variable_set(:@cache, nil)} + let(:ctx) { "http://example.com/preloaded" } + + before(:all) do + described_class.add_preloaded("http://example.com/preloaded", + described_class.parse({ 'foo' => "http://example.com/" })) + described_class.alias_preloaded("https://example.com/preloaded", "http://example.com/preloaded") + end + + after(:all) { described_class.instance_variable_set(:@cache, nil) } it "does not load referenced context" do expect(JSON::LD::API).not_to receive(:documentLoader).with(ctx, anything) @@ -215,24 +229,26 @@ def containers it "uses loaded context" do ec = subject.parse(ctx) expect(ec.send(:mappings)).to produce({ - "foo" => "http://example.com/" + "foo" => "http://example.com/" }, logger) end it "uses aliased context" do ec = subject.parse(ctx.sub('http', 'https')) expect(ec.send(:mappings)).to produce({ - "foo" => "http://example.com/" + "foo" => "http://example.com/" }, logger) end end end context "Array" do - let(:ctx) {[ - {"foo" => "http://example.com/foo"}, - {"bar" => "foo"} - ]} + let(:ctx) do + [ + { "foo" => "http://example.com/foo" }, + { "bar" => "foo" } + ] + end it "merges definitions from each context" do ec = subject.parse(ctx) @@ -243,21 +259,22 @@ def containers end it "merges definitions from remote contexts" do - JSON::LD::Context.instance_variable_set(:@cache, nil) - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) - rd2 = JSON::LD::API::RemoteDocument.new(%q({ + described_class.instance_variable_set(:@cache, nil) + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) + rd2 = JSON::LD::API::RemoteDocument.new('{ "@context": { "title": {"@id": "http://purl.org/dc/terms/title"} } - }), base_uri: "http://example.com/c2") + }', base_uri: "http://example.com/c2") expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c2", anything).and_yield(rd2) - ec = subject.parse(%w(http://example.com/context http://example.com/c2)) + ec = subject.parse(%w[http://example.com/context http://example.com/c2]) expect(ec.send(:mappings)).to produce({ - "xsd" => "http://www.w3.org/2001/XMLSchema#", - "name" => "http://xmlns.com/foaf/0.1/name", + "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", - "title" => "http://purl.org/dc/terms/title" + "avatar" => "http://xmlns.com/foaf/0.1/avatar", + "title" => "http://purl.org/dc/terms/title" }, logger) end end @@ -295,7 +312,7 @@ def containers it "maps term with @id" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/"} + "foo" => { "@id" => "http://example.com/" } }).send(:mappings)).to produce({ "foo" => "http://example.com/" }, logger) @@ -304,7 +321,7 @@ def containers it "maps term with blank node @id (with deprecation)" do expect do expect(subject.parse({ - "foo" => {"@id" => "_:bn"} + "foo" => { "@id" => "_:bn" } }).send(:mappings)).to produce({ "foo" => RDF::Node("bn") }, logger) @@ -314,7 +331,7 @@ def containers it "warns and ignores keyword-like term" do expect do expect(subject.parse({ - "@foo" => {"@id" => "http://example.org/foo"} + "@foo" => { "@id" => "http://example.org/foo" } }).send(:mappings)).to produce({}, logger) end.to write("Terms beginning with '@' are reserved").to(:error) end @@ -322,7 +339,7 @@ def containers it "maps '@' as a term" do expect do expect(subject.parse({ - "@" => {"@id" => "http://example.org/@"} + "@" => { "@id" => "http://example.org/@" } }).send(:mappings)).to produce({ "@" => "http://example.org/@" }, logger) @@ -332,7 +349,7 @@ def containers it "maps '@foo.bar' as a term" do expect do expect(subject.parse({ - "@foo.bar" => {"@id" => "http://example.org/foo.bar"} + "@foo.bar" => { "@id" => "http://example.org/foo.bar" } }).send(:mappings)).to produce({ "@foo.bar" => "http://example.org/foo.bar" }, logger) @@ -341,7 +358,7 @@ def containers it "associates @list container mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@container" => "@list"} + "foo" => { "@id" => "http://example.com/", "@container" => "@list" } }).containers).to produce({ "foo" => Set["@list"] }, logger) @@ -349,7 +366,7 @@ def containers it "associates @type container mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@container" => "@type"} + "foo" => { "@id" => "http://example.com/", "@container" => "@type" } }).containers).to produce({ "foo" => Set["@type"] }, logger) @@ -357,7 +374,7 @@ def containers it "associates @id container mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@container" => "@id"} + "foo" => { "@id" => "http://example.com/", "@container" => "@id" } }).containers).to produce({ "foo" => Set["@id"] }, logger) @@ -365,7 +382,7 @@ def containers it "associates @id type mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@type" => "@id"} + "foo" => { "@id" => "http://example.com/", "@type" => "@id" } }).coercions).to produce({ "foo" => "@id" }, logger) @@ -373,7 +390,7 @@ def containers it "associates @json type mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@type" => "@json"} + "foo" => { "@id" => "http://example.com/", "@type" => "@json" } }).coercions).to produce({ "foo" => "@json" }, logger) @@ -381,7 +398,7 @@ def containers it "associates type mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@type" => RDF::XSD.string.to_s} + "foo" => { "@id" => "http://example.com/", "@type" => RDF::XSD.string.to_s } }).coercions).to produce({ "foo" => RDF::XSD.string }, logger) @@ -389,7 +406,7 @@ def containers it "associates language mapping with term" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@language" => "en"} + "foo" => { "@id" => "http://example.com/", "@language" => "en" } }).send(:languages)).to produce({ "foo" => "en" }, logger) @@ -419,37 +436,37 @@ def containers context "with null" do it "removes @language if set to null" do expect(subject.parse([ - { - "@language" => "en" - }, - { - "@language" => nil - } - ]).default_language).to produce(nil, logger) + { + "@language" => "en" + }, + { + "@language" => nil + } + ]).default_language).to produce(nil, logger) end it "removes @vocab if set to null" do expect(subject.parse([ - { - "@vocab" => "http://schema.org/" - }, - { - "@vocab" => nil - } - ]).vocab).to produce(nil, logger) + { + "@vocab" => "http://schema.org/" + }, + { + "@vocab" => nil + } + ]).vocab).to produce(nil, logger) end it "removes term if set to null with @vocab" do expect(subject.parse([ - { - "@vocab" => "http://schema.org/", - "term" => nil - } - ]).send(:mappings)).to produce({"term" => nil}, logger) + { + "@vocab" => "http://schema.org/", + "term" => nil + } + ]).send(:mappings)).to produce({ "term" => nil }, logger) end it "loads initial context" do - init_ec = JSON::LD::Context.new + init_ec = described_class.new nil_ec = subject.parse(nil) expect(nil_ec.default_language).to eq init_ec.default_language expect(nil_ec.send(:languages)).to eq init_ec.send(:languages) @@ -459,29 +476,35 @@ def containers end it "removes a term definition" do - expect(subject.parse({"name" => nil}).send(:mapping, "name")).to be_nil + expect(subject.parse({ "name" => nil }).send(:mapping, "name")).to be_nil end end - context "@propagate" do it "generates an InvalidPropagateValue error if not a boolean" do - expect {subject.parse({'@version' => 1.1, '@propagate' => "String"})}.to raise_error(JSON::LD::JsonLdError::InvalidPropagateValue) + expect do + subject.parse({ '@version' => 1.1, + '@propagate' => "String" }) + end.to raise_error(JSON::LD::JsonLdError::InvalidPropagateValue) end end context "@import" do - before(:each) {JSON::LD::Context.instance_variable_set(:@cache, nil)} + before { described_class.instance_variable_set(:@cache, nil) } + it "generates an InvalidImportValue error if not a string" do - expect {subject.parse({'@version' => 1.1, '@import' => true})}.to raise_error(JSON::LD::JsonLdError::InvalidImportValue) + expect do + subject.parse({ '@version' => 1.1, '@import' => true }) + end.to raise_error(JSON::LD::JsonLdError::InvalidImportValue) end it "retrieves remote context" do - expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) - ec = subject.parse(JSON.parse %({ + expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) + ec = subject.parse(JSON.parse(%({ "@version": 1.1, "@import": "http://example.com/context" - })) + }))) expect(ec.term_definitions).to include("avatar") end end @@ -489,109 +512,116 @@ def containers describe "Syntax Errors" do { - "malformed JSON" => StringIO.new(%q({"@context": {"foo" "http://malformed/"})), - "no @id, @type, or @container" => {"foo" => {}}, - "value as array" => {"foo" => []}, - "@id as object" => {"foo" => {"@id" => {}}}, - "@id as array of object" => {"foo" => {"@id" => [{}]}}, - "@id as array of null" => {"foo" => {"@id" => [nil]}}, - "@type as object" => {"foo" => {"@type" => {}}}, - "@type as array" => {"foo" => {"@type" => []}}, - "@type as @list" => {"foo" => {"@type" => "@list"}}, - "@type as @none" => {"@version" => 1.1, "foo" => {"@type" => "@none"}}, - "@type as @set" => {"foo" => {"@type" => "@set"}}, - "@container as object" => {"foo" => {"@container" => {}}}, - "@container as empty array" => {"foo" => {"@container" => []}}, - "@container as string" => {"foo" => {"@container" => "true"}}, - "@context which is invalid" => {"foo" => {"@context" => {"bar" => []}}}, - "@language as @id" => {"@language" => {"@id" => "http://example.com/"}}, - "@direction as foo" => {"@direction" => "foo"}, - "@vocab as @id" => {"@vocab" => {"@id" => "http://example.com/"}}, - "@prefix string" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => "str"}}, - "@prefix array" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => []}}, - "@prefix object" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => {}}}, + "malformed JSON" => StringIO.new('{"@context": {"foo" "http://malformed/"}'), + "no @id, @type, or @container" => { "foo" => {} }, + "value as array" => { "foo" => [] }, + "@id as object" => { "foo" => { "@id" => {} } }, + "@id as array of object" => { "foo" => { "@id" => [{}] } }, + "@id as array of null" => { "foo" => { "@id" => [nil] } }, + "@type as object" => { "foo" => { "@type" => {} } }, + "@type as array" => { "foo" => { "@type" => [] } }, + "@type as @list" => { "foo" => { "@type" => "@list" } }, + "@type as @none" => { "@version" => 1.1, "foo" => { "@type" => "@none" } }, + "@type as @set" => { "foo" => { "@type" => "@set" } }, + "@container as object" => { "foo" => { "@container" => {} } }, + "@container as empty array" => { "foo" => { "@container" => [] } }, + "@container as string" => { "foo" => { "@container" => "true" } }, + "@context which is invalid" => { "foo" => { "@context" => { "bar" => [] } } }, + "@language as @id" => { "@language" => { "@id" => "http://example.com/" } }, + "@direction as foo" => { "@direction" => "foo" }, + "@vocab as @id" => { "@vocab" => { "@id" => "http://example.com/" } }, + "@prefix string" => { "foo" => { "@id" => 'http://example.org/', "@prefix" => "str" } }, + "@prefix array" => { "foo" => { "@id" => 'http://example.org/', "@prefix" => [] } }, + "@prefix object" => { "foo" => { "@id" => 'http://example.org/', "@prefix" => {} } }, "IRI term expands to different IRI" => { "ex" => "http://example.com/", "ex2" => "http://example.com/2/", "ex:foo" => "ex2:foo" - }, + }, "IRI term expands to different IRI (reverse)" => { "ex" => "http://example.com/", "ex2" => "http://example.com/2/", - "ex:foo" => {"@reverse" => "ex2:foo"} + "ex:foo" => { "@reverse" => "ex2:foo" } } }.each do |title, context| it title do - expect { + expect do ec = subject.parse(context) expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) + end.to raise_error(JSON::LD::JsonLdError) end end context "1.0" do - let(:context) {JSON::LD::Context.new(logger: logger, validate: true, processingMode: 'json-ld-1.0')} + let(:context) { described_class.new(logger: logger, validate: true, processingMode: 'json-ld-1.0') } + { - "@context" => {"foo" => {"@id" => 'http://example.org/', "@context" => {}}}, - "@container @id" => {"foo" => {"@container" => "@id"}}, - "@container @type" => {"foo" => {"@container" => "@type"}}, - "@nest" => {"foo" => {"@id" => 'http://example.org/', "@nest" => "@nest"}}, - "@type as @none" => {"foo" => {"@type" => "@none"}}, - "@type as @json" => {"foo" => {"@type" => "@json"}}, - "@prefix" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => true}}, + "@context" => { "foo" => { "@id" => 'http://example.org/', "@context" => {} } }, + "@container @id" => { "foo" => { "@container" => "@id" } }, + "@container @type" => { "foo" => { "@container" => "@type" } }, + "@nest" => { "foo" => { "@id" => 'http://example.org/', "@nest" => "@nest" } }, + "@type as @none" => { "foo" => { "@type" => "@none" } }, + "@type as @json" => { "foo" => { "@type" => "@json" } }, + "@prefix" => { "foo" => { "@id" => 'http://example.org/', "@prefix" => true } } }.each do |title, context| it title do - expect { + expect do ec = subject.parse(context) expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) + end.to raise_error(JSON::LD::JsonLdError) end end it "generates InvalidContextEntry if using @propagate" do - expect {context.parse({'@propagate' => true})}.to raise_error(JSON::LD::JsonLdError::InvalidContextEntry) + expect { context.parse({ '@propagate' => true }) }.to raise_error(JSON::LD::JsonLdError::InvalidContextEntry) end it "generates InvalidContextEntry if using @import" do - expect {context.parse({'@import' => "location"})}.to raise_error(JSON::LD::JsonLdError::InvalidContextEntry) + expect do + context.parse({ '@import' => "location" }) + end.to raise_error(JSON::LD::JsonLdError::InvalidContextEntry) end - (JSON::LD::KEYWORDS - %w(@base @language @version @protected @propagate @vocab)).each do |kw| + (JSON::LD::KEYWORDS - %w[@base @language @version @protected @propagate @vocab]).each do |kw| it "does not redefine #{kw} with an @container" do - expect { - ec = subject.parse({kw => {"@container" => "@set"}}) + expect do + ec = subject.parse({ kw => { "@container" => "@set" } }) expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) + end.to raise_error(JSON::LD::JsonLdError) end end end - (JSON::LD::KEYWORDS - %w(@base @direction @language @protected @propagate @import @version @vocab)).each do |kw| + (JSON::LD::KEYWORDS - %w[@base @direction @language @protected @propagate @import @version @vocab]).each do |kw| it "does not redefine #{kw} as a string" do - expect { - ec = subject.parse({kw => "http://example.com/"}) + expect do + ec = subject.parse({ kw => "http://example.com/" }) expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) + end.to raise_error(JSON::LD::JsonLdError) end it "does not redefine #{kw} with an @id" do - expect { - ec = subject.parse({kw => {"@id" => "http://example.com/"}}) + expect do + ec = subject.parse({ kw => { "@id" => "http://example.com/" } }) expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) + end.to raise_error(JSON::LD::JsonLdError) end - it "does not redefine #{kw} with an @container" do - expect { - ec = subject.parse({"@version" => 1.1, kw => {"@container" => "@set"}}) - expect(ec.serialize).to produce({}, logger) - }.to raise_error(JSON::LD::JsonLdError) - end unless kw == '@type' + unless kw == '@type' + it "does not redefine #{kw} with an @container" do + expect do + ec = subject.parse({ "@version" => 1.1, kw => { "@container" => "@set" } }) + expect(ec.serialize).to produce({}, logger) + end.to raise_error(JSON::LD::JsonLdError) + end + end + + next unless kw == '@type' it "redefines #{kw} with an @container" do - ec = subject.parse({kw => {"@container" => "@set"}}) + ec = subject.parse({ kw => { "@container" => "@set" } }) expect(ec.as_array('@type')).to be_truthy - end if kw == '@type' + end end end end @@ -600,9 +630,9 @@ def containers it "sets to json-ld-1.1 if @version: 1.1" do [ %({"@version": 1.1}), - %([{"@version": 1.1}]), + %([{"@version": 1.1}]) ].each do |str| - ctx = JSON::LD::Context.parse(::JSON.parse(str)) + ctx = described_class.parse(JSON.parse(str)) expect(ctx.processingMode).to eql "json-ld-1.1" end end @@ -614,22 +644,27 @@ def containers 1.0, "foo" ].each do |vers| - expect {JSON::LD::Context.parse({"@version" => vers})}.to raise_error(JSON::LD::JsonLdError::InvalidVersionValue) + expect do + described_class.parse({ "@version" => vers }) + end.to raise_error(JSON::LD::JsonLdError::InvalidVersionValue) end end it "raises ProcessingModeConflict if provided processing mode conflicts with context" do - expect {JSON::LD::Context.parse({"@version" => 1.1}, processingMode: "json-ld-1.0")}.to raise_error(JSON::LD::JsonLdError::ProcessingModeConflict) + expect do + described_class.parse({ "@version" => 1.1 }, + processingMode: "json-ld-1.0") + end.to raise_error(JSON::LD::JsonLdError::ProcessingModeConflict) end it "does not raise ProcessingModeConflict nested context is different from starting context" do - expect {JSON::LD::Context.parse([{}, {"@version" => 1.1}])}.not_to raise_error + expect { described_class.parse([{}, { "@version" => 1.1 }]) }.not_to raise_error end end describe "#merge" do it "creates a new context with components of each" do - c2 = JSON::LD::Context.parse({'foo' => "http://example.com/"}) + c2 = described_class.parse({ 'foo' => "http://example.com/" }) cm = context.merge(c2) expect(cm).not_to equal context expect(cm).not_to equal c2 @@ -638,9 +673,10 @@ def containers end describe "#serialize" do - before {JSON::LD::Context.instance_variable_set(:@cache, nil)} + before { described_class.instance_variable_set(:@cache, nil) } + it "context hash" do - ctx = {"foo" => "http://example.com/"} + ctx = { "foo" => "http://example.com/" } ec = subject.parse(ctx) expect(ec.serialize).to produce({ @@ -667,8 +703,8 @@ def containers end it "term mappings" do - c = subject. - parse({'foo' => "http://example.com/"}) + c = subject + .parse({ 'foo' => "http://example.com/" }) expect(c.serialize).to produce({ "@context" => { "foo" => "http://example.com/" @@ -678,13 +714,13 @@ def containers it "@context" do expect(subject.parse({ - "foo" => {"@id" => "http://example.com/", "@context" => {"bar" => "http://example.com/baz"}} - }). - serialize).to produce({ + "foo" => { "@id" => "http://example.com/", "@context" => { "bar" => "http://example.com/baz" } } + }) + .serialize).to produce({ "@context" => { "foo" => { "@id" => "http://example.com/", - "@context" => {"bar" => "http://example.com/baz"} + "@context" => { "bar" => "http://example.com/baz" } } } }, logger) @@ -693,45 +729,45 @@ def containers it "@type with dependent prefixes in a single context" do expect(subject.parse({ 'xsd' => "http://www.w3.org/2001/XMLSchema#", - 'homepage' => {'@id' => RDF::Vocab::FOAF.homepage.to_s, '@type' => '@id'} - }). - serialize).to produce({ + 'homepage' => { '@id' => RDF::Vocab::FOAF.homepage.to_s, '@type' => '@id' } + }) + .serialize).to produce({ "@context" => { "xsd" => RDF::XSD.to_uri.to_s, - "homepage" => {"@id" => RDF::Vocab::FOAF.homepage.to_s, "@type" => "@id"} + "homepage" => { "@id" => RDF::Vocab::FOAF.homepage.to_s, "@type" => "@id" } } }, logger) end it "@list with @id definition in a single context" do expect(subject.parse({ - 'knows' => {'@id' => RDF::Vocab::FOAF.knows.to_s, '@container' => '@list'} - }). - serialize).to produce({ + 'knows' => { '@id' => RDF::Vocab::FOAF.knows.to_s, '@container' => '@list' } + }) + .serialize).to produce({ "@context" => { - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list" } } }, logger) end it "@set with @id definition in a single context" do expect(subject.parse({ - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set" } + }) + .serialize).to produce({ "@context" => { - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set" } } }, logger) end it "@language with @id definition in a single context" do expect(subject.parse({ - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en"} - }). - serialize).to produce({ + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en" } + }) + .serialize).to produce({ "@context" => { - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en"} + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en" } } }, logger) end @@ -739,12 +775,12 @@ def containers it "@language with @id definition in a single context and equivalent default" do expect(subject.parse({ "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => 'en'} - }). - serialize).to produce({ + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => 'en' } + }) + .serialize).to produce({ "@context" => { "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => 'en'} + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => 'en' } } }, logger) end @@ -752,12 +788,12 @@ def containers it "@language with @id definition in a single context and different default" do expect(subject.parse({ "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "de"} - }). - serialize).to produce({ + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "de" } + }) + .serialize).to produce({ "@context" => { "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "de"} + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "de" } } }, logger) end @@ -765,45 +801,45 @@ def containers it "null @language with @id definition in a single context and default" do expect(subject.parse({ "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => nil} - }). - serialize).to produce({ + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => nil } + }) + .serialize).to produce({ "@context" => { "@language" => 'en', - "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => nil} + "name" => { "@id" => RDF::Vocab::FOAF.name.to_s, "@language" => nil } } }, logger) end it "prefix with @type and @list" do expect(subject.parse({ - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list" } + }) + .serialize).to produce({ "@context" => { - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list" } } }, logger) end it "prefix with @type and @set" do expect(subject.parse({ - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set" } + }) + .serialize).to produce({ "@context" => { - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set" } } }, logger) end it "prefix with @type @json" do expect(subject.parse({ - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json" } + }) + .serialize).to produce({ "@context" => { - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json" } } }, logger) end @@ -814,8 +850,8 @@ def containers "foaf:knows" => { "@container" => "@list" } - }). - serialize).to produce({ + }) + .serialize).to produce({ "@context" => { "foaf" => RDF::Vocab::FOAF.to_uri.to_s, "foaf:knows" => { @@ -828,12 +864,12 @@ def containers it "does not use aliased @id in key position" do expect(subject.parse({ "id" => "@id", - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list" } + }) + .serialize).to produce({ "@context" => { "id" => "@id", - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list" } } }, logger) end @@ -845,8 +881,8 @@ def containers "foaf:homepage" => { "@type" => "@id" } - }). - serialize).to produce({ + }) + .serialize).to produce({ "@context" => { "foaf" => RDF::Vocab::FOAF.to_uri.to_s, "id" => "@id", @@ -861,13 +897,13 @@ def containers expect(subject.parse({ "foaf" => RDF::Vocab::FOAF.to_uri.to_s, "type" => "@type", - "foaf:homepage" => {"@type" => "@id"} - }). - serialize).to produce({ + "foaf:homepage" => { "@type" => "@id" } + }) + .serialize).to produce({ "@context" => { "foaf" => RDF::Vocab::FOAF.to_uri.to_s, "type" => "@type", - "foaf:homepage" => {"@type" => "@id"} + "foaf:homepage" => { "@type" => "@id" } } }, logger) end @@ -875,12 +911,12 @@ def containers it "does not use aliased @container" do expect(subject.parse({ "container" => "@container", - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"} - }). - serialize).to produce({ + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list" } + }) + .serialize).to produce({ "@context" => { "container" => "@container", - "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"} + "knows" => { "@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list" } } }, logger) end @@ -888,12 +924,12 @@ def containers it "compacts IRIs to Compact IRIs" do expect(subject.parse({ "ex" => 'http://example.org/', - "term" => {"@id" => "ex:term", "@type" => "ex:datatype"} - }). - serialize).to produce({ + "term" => { "@id" => "ex:term", "@type" => "ex:datatype" } + }) + .serialize).to produce({ "@context" => { "ex" => 'http://example.org/', - "term" => {"@id" => "ex:term", "@type" => "ex:datatype"} + "term" => { "@id" => "ex:term", "@type" => "ex:datatype" } } }, logger) end @@ -901,39 +937,40 @@ def containers it "compacts IRIs using @vocab" do expect(subject.parse({ "@vocab" => 'http://example.org/', - "term" => {"@id" => "http://example.org/term", "@type" => "datatype"} - }). - serialize).to produce({ + "term" => { "@id" => "http://example.org/term", "@type" => "datatype" } + }) + .serialize).to produce({ "@context" => { "@vocab" => 'http://example.org/', - "term" => {"@type" => "datatype"} + "term" => { "@type" => "datatype" } } }, logger) end context "invalid term definitions" do { - "empty term": { - input: {"" => "http://blank-term/"} + 'empty term': { + input: { "" => "http://blank-term/" } }, - "extra key": { - input: {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}} + 'extra key': { + input: { "foo" => { "@id" => "http://example.com/foo", "@baz" => "foobar" } } } }.each do |title, params| it title do - expect {subject.parse(params[:input])}.to raise_error(JSON::LD::JsonLdError::InvalidTermDefinition) + expect { subject.parse(params[:input]) }.to raise_error(JSON::LD::JsonLdError::InvalidTermDefinition) end end end - end describe "#to_rb" do - before(:all) {JSON::LD::Context.instance_variable_set(:@cache, nil)} - subject { - allow(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc) + subject do + allow(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", + anything).and_yield(remote_doc) context.parse("http://example.com/context") - } + end + + before(:all) { described_class.instance_variable_set(:@cache, nil) } it "encodes as utf-8" do expect(subject.to_rb).to match(/encoding: utf-8/) @@ -960,14 +997,14 @@ def containers end describe "#base=" do - subject { + subject do context.parse({ '@base' => 'http://base/', '@vocab' => 'http://vocab/', 'ex' => 'http://example.org/', '_' => 'http://underscore/' }) - } + end it "sets new base uri given an absolute uri" do subject.base = "http://example.org/" @@ -981,11 +1018,11 @@ def containers end describe "#vocab=" do - subject { + subject do context.parse({ - '@base' => 'http://base/resource', + '@base' => 'http://base/resource' }) - } + end it "sets vocab from absolute iri" do subject.vocab = "http://example.org/" @@ -1023,21 +1060,21 @@ def containers end describe "#expand_iri" do - subject { + subject do context.parse({ '@base' => 'http://base/base', '@vocab' => 'http://vocab/', 'ex' => 'http://example.org/', '_' => 'http://underscore/' }) - } + end it "bnode" do expect(subject.expand_iri("_:a")).to be_a(RDF::Node) end context "keywords" do - %w(id type).each do |kw| + %w[id type].each do |kw| it "expands #{kw} to @#{kw}" do subject.set_mapping(kw, "@#{kw}") expect(subject.expand_iri(kw, vocab: true)).to produce("@#{kw}", logger) @@ -1048,22 +1085,22 @@ def containers context "relative IRI" do context "with no options" do { - "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], - "term" => ["ex", RDF::URI("ex")], - "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], - "#frag" => ["#frag", RDF::URI("#frag")], - "#frag:2" => ["#frag:2", RDF::URI("#frag:2")], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", RDF::URI("foo")], - "relative" => ["foo/bar", RDF::URI("foo/bar")], - "dotseg" => ["../foo/bar", RDF::URI("../foo/bar")], - "empty term" => ["", RDF::URI("")], - "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")], + "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], + "term" => ["ex", RDF::URI("ex")], + "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], + "#frag" => ["#frag", RDF::URI("#frag")], + "#frag:2" => ["#frag:2", RDF::URI("#frag:2")], + "keyword" => ["@type", "@type"], + "unmapped" => ["foo", RDF::URI("foo")], + "relative" => ["foo/bar", RDF::URI("foo/bar")], + "dotseg" => ["../foo/bar", RDF::URI("../foo/bar")], + "empty term" => ["", RDF::URI("")], + "another abs IRI" => ["ex://foo", RDF::URI("ex://foo")], "absolute IRI looking like a Compact IRI" => ["foo:bar", RDF::URI("foo:bar")], - "bnode" => ["_:t0", RDF::Node("t0")], - "_" => ["_", RDF::URI("_")], - "@" => ["@", RDF::URI("@")], + "bnode" => ["_:t0", RDF::Node("t0")], + "_" => ["_", RDF::URI("_")], + "@" => ["@", RDF::URI("@")] }.each do |title, (input, result)| it title do expect(subject.expand_iri(input)).to produce(result, logger) @@ -1073,22 +1110,22 @@ def containers context "with base IRI" do { - "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], - "term" => ["ex", RDF::URI("http://base/ex")], - "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], - "#frag" => ["#frag", RDF::URI("http://base/base#frag")], - "#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", RDF::URI("http://base/foo")], - "relative" => ["foo/bar", RDF::URI("http://base/foo/bar")], - "dotseg" => ["../foo/bar", RDF::URI("http://base/foo/bar")], - "empty term" => ["", RDF::URI("http://base/base")], - "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")], + "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], + "term" => ["ex", RDF::URI("http://base/ex")], + "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], + "#frag" => ["#frag", RDF::URI("http://base/base#frag")], + "#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")], + "keyword" => ["@type", "@type"], + "unmapped" => ["foo", RDF::URI("http://base/foo")], + "relative" => ["foo/bar", RDF::URI("http://base/foo/bar")], + "dotseg" => ["../foo/bar", RDF::URI("http://base/foo/bar")], + "empty term" => ["", RDF::URI("http://base/base")], + "another abs IRI" => ["ex://foo", RDF::URI("ex://foo")], "absolute IRI looking like a compact IRI" => ["foo:bar", RDF::URI("foo:bar")], - "bnode" => ["_:t0", RDF::Node("t0")], - "_" => ["_", RDF::URI("http://base/_")], - "@" => ["@", RDF::URI("http://base/@")], + "bnode" => ["_:t0", RDF::Node("t0")], + "_" => ["_", RDF::URI("http://base/_")], + "@" => ["@", RDF::URI("http://base/@")] }.each do |title, (input, result)| it title do expect(subject.expand_iri(input, documentRelative: true)).to produce(result, logger) @@ -1098,21 +1135,21 @@ def containers context "@vocab" do { - "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], - "term" => ["ex", RDF::URI("http://example.org/")], - "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], - "#frag" => ["#frag", RDF::URI("http://vocab/#frag")], - "#frag:2" => ["#frag:2", RDF::URI("http://vocab/#frag:2")], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", RDF::URI("http://vocab/foo")], - "relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")], - "dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")], - "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")], + "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], + "term" => ["ex", RDF::URI("http://example.org/")], + "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], + "#frag" => ["#frag", RDF::URI("http://vocab/#frag")], + "#frag:2" => ["#frag:2", RDF::URI("http://vocab/#frag:2")], + "keyword" => ["@type", "@type"], + "unmapped" => ["foo", RDF::URI("http://vocab/foo")], + "relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")], + "dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")], + "another abs IRI" => ["ex://foo", RDF::URI("ex://foo")], "absolute IRI looking like a compact IRI" => ["foo:bar", RDF::URI("foo:bar")], - "bnode" => ["_:t0", RDF::Node("t0")], - "_" => ["_", RDF::URI("http://underscore/")], - "@" => ["@", RDF::URI("http://vocab/@")], + "bnode" => ["_:t0", RDF::Node("t0")], + "_" => ["_", RDF::URI("http://underscore/")], + "@" => ["@", RDF::URI("http://vocab/@")] }.each do |title, (input, result)| it title do expect(subject.expand_iri(input, vocab: true)).to produce(result, logger) @@ -1120,30 +1157,30 @@ def containers end context "set to ''" do - subject { + subject do context.parse({ '@base' => 'http://base/base', '@vocab' => '', 'ex' => 'http://example.org/', '_' => 'http://underscore/' }) - } + end { - "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], - "term" => ["ex", RDF::URI("http://example.org/")], - "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], - "#frag" => ["#frag", RDF::URI("http://base/base#frag")], - "#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", RDF::URI("http://base/basefoo")], - "relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")], - "dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")], - "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")], + "absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")], + "term" => ["ex", RDF::URI("http://example.org/")], + "prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")], + "#frag" => ["#frag", RDF::URI("http://base/base#frag")], + "#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")], + "keyword" => ["@type", "@type"], + "unmapped" => ["foo", RDF::URI("http://base/basefoo")], + "relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")], + "dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")], + "another abs IRI" => ["ex://foo", RDF::URI("ex://foo")], "absolute IRI looking like a compact IRI" => - ["foo:bar", RDF::URI("foo:bar")], - "bnode" => ["_:t0", RDF::Node("t0")], - "_" => ["_", RDF::URI("http://underscore/")], + ["foo:bar", RDF::URI("foo:bar")], + "bnode" => ["_:t0", RDF::Node("t0")], + "_" => ["_", RDF::URI("http://underscore/")] }.each do |title, (input, result)| it title do expect(subject.expand_iri(input, vocab: true)).to produce(result, logger) @@ -1152,45 +1189,46 @@ def containers end it "expand-0110" do - ctx = JSON::LD::Context.parse({ + ctx = described_class.parse({ "@base" => "http://example.com/some/deep/directory/and/file/", "@vocab" => "/relative" }) - expect(ctx.expand_iri("#fragment-works", vocab: true)).to produce("http://example.com/relative#fragment-works", logger) + expect(ctx.expand_iri("#fragment-works", + vocab: true)).to produce("http://example.com/relative#fragment-works", logger) end end end end describe "#compact_iri" do - subject { + subject do c = context.parse({ - '@base' => 'http://base/', - "xsd" => "http://www.w3.org/2001/XMLSchema#", - 'ex' => 'http://example.org/', - '_' => 'http://underscore/', - 'rex' => {'@reverse' => "ex"}, - 'lex' => {'@id' => 'ex', '@language' => 'en'}, - 'tex' => {'@id' => 'ex', '@type' => 'xsd:string'}, - 'exp' => {'@id' => 'ex:pert'}, - 'experts' => {'@id' => 'ex:perts'}, + '@base' => 'http://base/', + "xsd" => "http://www.w3.org/2001/XMLSchema#", + 'ex' => 'http://example.org/', + '_' => 'http://underscore/', + 'rex' => { '@reverse' => "ex" }, + 'lex' => { '@id' => 'ex', '@language' => 'en' }, + 'tex' => { '@id' => 'ex', '@type' => 'xsd:string' }, + 'exp' => { '@id' => 'ex:pert' }, + 'experts' => { '@id' => 'ex:perts' } }) logger.clear c - } + end { "nil" => [nil, nil], - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=>["ex:perts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["ex:perts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input)}.to raise_error(result) + expect { subject.compact_iri(input) }.to raise_error(result) else expect(subject.compact_iri(input)).to produce(result, logger) end @@ -1199,17 +1237,17 @@ def containers context "with :vocab option" do { - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["http://base/foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=> ["experts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], + "keyword" => ["@type", "@type"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["http://base/foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["experts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input, vocab: true)}.to raise_error(result) + expect { subject.compact_iri(input, vocab: true) }.to raise_error(result) else expect(subject.compact_iri(input, vocab: true)).to produce(result, logger) end @@ -1218,20 +1256,20 @@ def containers end context "with @vocab" do - before(:each) { subject.vocab = "http://example.org/"} + before { subject.vocab = "http://example.org/" } { - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["suffix", "http://example.org/suffix"], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["http://base/foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=> ["experts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["suffix", "http://example.org/suffix"], + "keyword" => ["@type", "@type"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["http://base/foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["experts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input, vocab: true)}.to raise_error(result) + expect { subject.compact_iri(input, vocab: true) }.to raise_error(result) else expect(subject.compact_iri(input, vocab: true)).to produce(result, logger) end @@ -1241,28 +1279,28 @@ def containers it "does not use @vocab if it would collide with a term" do subject.set_mapping("name", "http://xmlns.com/foaf/0.1/name") subject.set_mapping("ex", nil) - expect(subject.compact_iri("http://example.org/name", vocab: true)). - not_to produce("name", logger) + expect(subject.compact_iri("http://example.org/name", vocab: true)) + .not_to produce("name", logger) end context "with @vocab: relative" do - before(:each) { + before do subject.vocab = nil subject.base = 'http://base/base' - } + end { - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["http://base/foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=> ["experts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], + "keyword" => ["@type", "@type"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["http://base/foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["experts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input, vocab: true)}.to raise_error(result) + expect { subject.compact_iri(input, vocab: true) }.to raise_error(result) else expect(subject.compact_iri(input, vocab: true)).to produce(result, logger) end @@ -1276,38 +1314,39 @@ def containers c = subject.parse({ "xsd" => RDF::XSD.to_s, "plain" => "http://example.com/plain", - "lang" => {"@id" => "http://example.com/lang", "@language" => "en"}, - "dir" => {"@id" => "http://example.com/dir", "@direction" => "ltr"}, - "langdir" => {"@id" => "http://example.com/langdir", "@language" => "en", "@direction" => "ltr"}, - "bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean"}, - "integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer"}, - "double" => {"@id" => "http://example.com/double", "@type" => "xsd:double"}, - "date" => {"@id" => "http://example.com/date", "@type" => "xsd:date"}, - "id" => {"@id" => "http://example.com/id", "@type" => "@id"}, - 'graph' => {'@id' => 'http://example.com/graph', '@container' => '@graph'}, - 'json' => {'@id' => 'http://example.com/json', '@type' => '@json'}, - - "list_plain" => {"@id" => "http://example.com/plain", "@container" => "@list"}, - "list_lang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@list"}, - "list_bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@list"}, - "list_integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@list"}, - "list_double" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@list"}, - "list_date" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@list"}, - "list_id" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@list"}, - "list_graph" => {"@id" => "http://example.com/graph", "@type" => "@id", "@container" => "@list"}, - - "set_plain" => {"@id" => "http://example.com/plain", "@container" => "@set"}, - "set_lang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@set"}, - "set_bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@set"}, - "set_integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@set"}, - "set_double" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@set"}, - "set_date" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@set"}, - "set_id" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@set"}, - 'set_graph' => {'@id' => 'http://example.com/graph', '@container' => ['@graph', '@set']}, - - "map_lang" => {"@id" => "http://example.com/lang", "@container" => "@language"}, - - "set_map_lang" => {"@id" => "http://example.com/lang", "@container" => ["@language", "@set"]}, + "lang" => { "@id" => "http://example.com/lang", "@language" => "en" }, + "dir" => { "@id" => "http://example.com/dir", "@direction" => "ltr" }, + "langdir" => { "@id" => "http://example.com/langdir", "@language" => "en", "@direction" => "ltr" }, + "bool" => { "@id" => "http://example.com/bool", "@type" => "xsd:boolean" }, + "integer" => { "@id" => "http://example.com/integer", "@type" => "xsd:integer" }, + "double" => { "@id" => "http://example.com/double", "@type" => "xsd:double" }, + "date" => { "@id" => "http://example.com/date", "@type" => "xsd:date" }, + "id" => { "@id" => "http://example.com/id", "@type" => "@id" }, + 'graph' => { '@id' => 'http://example.com/graph', '@container' => '@graph' }, + 'json' => { '@id' => 'http://example.com/json', '@type' => '@json' }, + + "list_plain" => { "@id" => "http://example.com/plain", "@container" => "@list" }, + "list_lang" => { "@id" => "http://example.com/lang", "@language" => "en", "@container" => "@list" }, + "list_bool" => { "@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@list" }, + "list_integer" => { "@id" => "http://example.com/integer", "@type" => "xsd:integer", + "@container" => "@list" }, + "list_double" => { "@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@list" }, + "list_date" => { "@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@list" }, + "list_id" => { "@id" => "http://example.com/id", "@type" => "@id", "@container" => "@list" }, + "list_graph" => { "@id" => "http://example.com/graph", "@type" => "@id", "@container" => "@list" }, + + "set_plain" => { "@id" => "http://example.com/plain", "@container" => "@set" }, + "set_lang" => { "@id" => "http://example.com/lang", "@language" => "en", "@container" => "@set" }, + "set_bool" => { "@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@set" }, + "set_integer" => { "@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@set" }, + "set_double" => { "@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@set" }, + "set_date" => { "@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@set" }, + "set_id" => { "@id" => "http://example.com/id", "@type" => "@id", "@container" => "@set" }, + 'set_graph' => { '@id' => 'http://example.com/graph', '@container' => ['@graph', '@set'] }, + + "map_lang" => { "@id" => "http://example.com/lang", "@container" => "@language" }, + + "set_map_lang" => { "@id" => "http://example.com/lang", "@container" => ["@language", "@set"] } }) logger.clear c @@ -1315,21 +1354,21 @@ def containers # Prefered sets and maps over non sets or maps { - "set_plain" => [{"@value" => "foo"}], - "map_lang" => [{"@value" => "en", "@language" => "en"}], - "set_bool" => [{"@value" => "true", "@type" => "http://www.w3.org/2001/XMLSchema#boolean"}], - "set_integer" => [{"@value" => "1", "@type" => "http://www.w3.org/2001/XMLSchema#integer"}], - "set_id" => [{"@id" => "http://example.org/id"}], - "graph" => [{"@graph" => [{"@id" => "http://example.org/id"}]}], - 'json' => [{"@value" => {"some" => "json"}, "@type" => "@json"}], - 'dir' => [{"@value" => "dir", "@direction" => "ltr"}], - 'langdir' => [{"@value" => "lang dir", "@language" => "en", "@direction" => "ltr"}], + "set_plain" => [{ "@value" => "foo" }], + "map_lang" => [{ "@value" => "en", "@language" => "en" }], + "set_bool" => [{ "@value" => "true", "@type" => "http://www.w3.org/2001/XMLSchema#boolean" }], + "set_integer" => [{ "@value" => "1", "@type" => "http://www.w3.org/2001/XMLSchema#integer" }], + "set_id" => [{ "@id" => "http://example.org/id" }], + "graph" => [{ "@graph" => [{ "@id" => "http://example.org/id" }] }], + 'json' => [{ "@value" => { "some" => "json" }, "@type" => "@json" }], + 'dir' => [{ "@value" => "dir", "@direction" => "ltr" }], + 'langdir' => [{ "@value" => "lang dir", "@language" => "en", "@direction" => "ltr" }] }.each do |prop, values| context "uses #{prop}" do values.each do |value| it "for #{value.inspect}" do - expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: value, vocab: true)). - to produce(prop, logger) + expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: value, vocab: true)) + .to produce(prop, logger) end end end @@ -1338,28 +1377,29 @@ def containers # @language and @type with @list context "for @list" do { - "list_plain" => [ - [{"@value" => "foo"}], - [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => "baz"}], - [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}], - [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1.1}], - [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => true}], - [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}], - [{"@value" => "de", "@language" => "de"}, {"@value" => "jp", "@language" => "jp"}], - [{"@value" => true}], [{"@value" => false}], - [{"@value" => 1}], [{"@value" => 1.1}], + "list_plain" => [ + [{ "@value" => "foo" }], + [{ "@value" => "foo" }, { "@value" => "bar" }, { "@value" => "baz" }], + [{ "@value" => "foo" }, { "@value" => "bar" }, { "@value" => 1 }], + [{ "@value" => "foo" }, { "@value" => "bar" }, { "@value" => 1.1 }], + [{ "@value" => "foo" }, { "@value" => "bar" }, { "@value" => true }], + [{ "@value" => "foo" }, { "@value" => "bar" }, { "@value" => 1 }], + [{ "@value" => "de", "@language" => "de" }, { "@value" => "jp", "@language" => "jp" }], + [{ "@value" => true }], [{ "@value" => false }], + [{ "@value" => 1 }], [{ "@value" => 1.1 }] ], - "list_lang" => [[{"@value" => "en", "@language" => "en"}]], - "list_bool" => [[{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}]], - "list_integer" => [[{"@value" => "1", "@type" => RDF::XSD.integer.to_s}]], - "list_double" => [[{"@value" => "1", "@type" => RDF::XSD.double.to_s}]], - "list_date" => [[{"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}]], + "list_lang" => [[{ "@value" => "en", "@language" => "en" }]], + "list_bool" => [[{ "@value" => "true", "@type" => RDF::XSD.boolean.to_s }]], + "list_integer" => [[{ "@value" => "1", "@type" => RDF::XSD.integer.to_s }]], + "list_double" => [[{ "@value" => "1", "@type" => RDF::XSD.double.to_s }]], + "list_date" => [[{ "@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s }]] }.each do |prop, values| context "uses #{prop}" do values.each do |value| - it "for #{{"@list" => value}.inspect}" do - expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: {"@list" => value}, vocab: true)). - to produce(prop, logger) + it "for #{{ '@list' => value }.inspect}" do + expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: { "@list" => value }, + vocab: true)) + .to produce(prop, logger) end end end @@ -1370,16 +1410,16 @@ def containers context "Compact IRI compaction" do { "nil" => [nil, nil], - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=> ["ex:perts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["ex:perts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input)}.to raise_error(result) + expect { subject.compact_iri(input) }.to raise_error(result) else expect(subject.compact_iri(input)).to produce(result, logger) end @@ -1387,20 +1427,20 @@ def containers end context "and @vocab" do - before(:each) { subject.vocab = "http://example.org/"} + before { subject.vocab = "http://example.org/" } { - "absolute IRI" => ["http://example.com/", "http://example.com/"], - "prefix:suffix" => ["suffix", "http://example.org/suffix"], - "keyword" => ["@type", "@type"], - "unmapped" => ["foo", "foo"], - "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")], - "relative" => ["http://base/foo/bar", "http://base/foo/bar"], - "odd Compact IRI"=> ["experts", "http://example.org/perts"] + "absolute IRI" => ["http://example.com/", "http://example.com/"], + "prefix:suffix" => ["suffix", "http://example.org/suffix"], + "keyword" => ["@type", "@type"], + "unmapped" => %w[foo foo], + "bnode" => [JSON::LD::JsonLdError::IRIConfusedWithPrefix, RDF::Node("a")], + "relative" => ["http://base/foo/bar", "http://base/foo/bar"], + "odd Compact IRI" => ["experts", "http://example.org/perts"] }.each do |title, (result, input)| it title do if result.is_a?(Class) - expect {subject.compact_iri(input, vocab: true)}.to raise_error(result) + expect { subject.compact_iri(input, vocab: true) }.to raise_error(result) else expect(subject.compact_iri(input, vocab: true)).to produce(result, logger) end @@ -1411,7 +1451,7 @@ def containers context "compact-0018" do let(:ctx) do - subject.parse(JSON.parse %({ + subject.parse(JSON.parse(%({ "id1": "http://example.com/id1", "type1": "http://example.com/t1", "type2": "http://example.com/t2", @@ -1443,7 +1483,7 @@ def containers "@container": "@list", "@type": "type2" } - })) + }))) end { @@ -1455,7 +1495,7 @@ def containers '{ "@value": true}', '{ "@value": false}' ], - "term1" => %q({ + "term1" => '{ "@list": [ { "@value": "v1.1", "@language": "de" }, { "@value": "v1.2", "@language": "en" }, @@ -1464,8 +1504,8 @@ def containers { "@value": true}, { "@value": false} ] - }), - "term2" => %q({ + }', + "term2" => '{ "@list": [ { "@value": "v2.1", "@language": "en" }, { "@value": "v2.2", "@language": "en" }, @@ -1474,8 +1514,8 @@ def containers { "@value": "v2.5", "@language": "en" }, { "@value": "v2.6", "@language": "en" } ] - }), - "term3" => %q({ + }', + "term3" => '{ "@list": [ { "@value": "v3.1"}, { "@value": "v3.2"}, @@ -1484,8 +1524,8 @@ def containers { "@value": "v3.5"}, { "@value": "v3.6"} ] - }), - "term4" => %q({ + }', + "term4" => '{ "@list": [ { "@value": "v4.1", "@type": "http://example.com/t1" }, { "@value": "v4.2", "@type": "http://example.com/t1" }, @@ -1494,8 +1534,8 @@ def containers { "@value": "v4.5", "@type": "http://example.com/t1" }, { "@value": "v4.6", "@type": "http://example.com/t1" } ] - }), - "term5" => %q({ + }', + "term5" => '{ "@list": [ { "@value": "v5.1", "@type": "http://example.com/t2" }, { "@value": "v5.2", "@type": "http://example.com/t2" }, @@ -1504,12 +1544,12 @@ def containers { "@value": "v5.5", "@type": "http://example.com/t2" }, { "@value": "v5.6", "@type": "http://example.com/t2" } ] - }), + }' }.each do |term, value| [value].flatten.each do |v| it "Uses #{term} for #{v}" do - expect(ctx.compact_iri("http://example.com/term", value: JSON.parse(v), vocab: true)). - to produce(term, logger) + expect(ctx.compact_iri("http://example.com/term", value: JSON.parse(v), vocab: true)) + .to produce(term, logger) end end end @@ -1519,19 +1559,21 @@ def containers let(:ctx) do subject.parse({ "ex" => "http://example.org/ns#", - "ex:property" => {"@container" => "@list"} + "ex:property" => { "@container" => "@list" } }) end + it "Compact @id that is a property IRI when @container is @list" do - expect(ctx.compact_iri("http://example.org/ns#property", vocab: false)). - to produce("ex:property", logger) + expect(ctx.compact_iri("http://example.org/ns#property", vocab: false)) + .to produce("ex:property", logger) end end context "compact-0041" do let(:ctx) do - subject.parse({"name" => {"@id" => "http://example.com/property", "@container" => "@list"}}) + subject.parse({ "name" => { "@id" => "http://example.com/property", "@container" => "@list" } }) end + it "Does not use @list with @index" do expect(ctx.compact_iri("http://example.com/property", value: { "@list" => ["one item"], @@ -1542,55 +1584,61 @@ def containers end describe "#expand_value" do - subject { + subject do ctx = context.parse({ "dc" => RDF::Vocab::DC.to_uri.to_s, "ex" => "http://example.org/", "foaf" => RDF::Vocab::FOAF.to_uri.to_s, "xsd" => "http://www.w3.org/2001/XMLSchema#", - "foaf:age" => {"@type" => "xsd:integer"}, - "foaf:knows" => {"@type" => "@id"}, - "dc:created" => {"@type" => "xsd:date"}, - "ex:integer" => {"@type" => "xsd:integer"}, - "ex:double" => {"@type" => "xsd:double"}, - "ex:boolean" => {"@type" => "xsd:boolean"}, - "ex:none" => {"@type" => "@none"}, - "ex:json" => {"@type" => "@json"} + "foaf:age" => { "@type" => "xsd:integer" }, + "foaf:knows" => { "@type" => "@id" }, + "dc:created" => { "@type" => "xsd:date" }, + "ex:integer" => { "@type" => "xsd:integer" }, + "ex:double" => { "@type" => "xsd:double" }, + "ex:boolean" => { "@type" => "xsd:boolean" }, + "ex:none" => { "@type" => "@none" }, + "ex:json" => { "@type" => "@json" } }) logger.clear ctx - } + end - %w(boolean integer string dateTime date time).each do |dt| + %w[boolean integer string dateTime date time].each do |dt| it "expands datatype xsd:#{dt}" do - expect(subject.expand_value("foo", RDF::XSD[dt])).to produce({"@id" => "http://www.w3.org/2001/XMLSchema##{dt}"}, logger) + expect(subject.expand_value("foo", + RDF::XSD[dt])).to produce({ "@id" => "http://www.w3.org/2001/XMLSchema##{dt}" }, logger) end end { - "absolute IRI" => ["foaf:knows", "http://example.com/", {"@id" => "http://example.com/"}], - "term" => ["foaf:knows", "ex", {"@id" => "ex"}], - "prefix:suffix" => ["foaf:knows", "ex:suffix", {"@id" => "http://example.org/suffix"}], - "no IRI" => ["foo", "http://example.com/", {"@value" => "http://example.com/"}], - "no term" => ["foo", "ex", {"@value" => "ex"}], - "no prefix" => ["foo", "ex:suffix", {"@value" => "ex:suffix"}], - "integer" => ["foaf:age", "54", {"@value" => "54", "@type" => RDF::XSD.integer.to_s}], - "date " => ["dc:created", "2011-12-27Z", {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}], - "native boolean" => ["foo", true, {"@value" => true}], - "native integer" => ["foo", 1, {"@value" => 1}], - "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}], - "native date" => ["foo", Date.parse("2011-12-27"), {"@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s}], - "native dateTime" =>["foo", DateTime.parse("2011-12-27T10:11:12Z"), {"@value" => "2011-12-27T10:11:12Z", "@type" => RDF::XSD.dateTime.to_s}], - "ex:none string" => ["ex:none", "foo", {"@value" => "foo"}], - "ex:none boolean" =>["ex:none", true, {"@value" => true}], - "ex:none integer" =>["ex:none", 1, {"@value" => 1}], - "ex:none double" => ["ex:none", 1.1e1, {"@value" => 1.1E1}], - "ex:json string" => ["ex:json", "foo", {"@value" => "foo", "@type" => "@json"}], - "ex:json boolean" =>["ex:json", true, {"@value" => true, "@type" => "@json"}], - "ex:json integer" =>["ex:json", 1, {"@value" => 1, "@type" => "@json"}], - "ex:json double" => ["ex:json", 1.1e1, {"@value" => 1.1e1, "@type" => "@json"}], - "ex:json object" => ["ex:json", {"foo" => "bar"}, {"@value" => {"foo" => "bar"}, "@type" => "@json"}], - "ex:json array" => ["ex:json", [{"foo" => "bar"}], {"@value" => [{"foo" => "bar"}], "@type" => "@json"}], + "absolute IRI" => ["foaf:knows", "http://example.com/", { "@id" => "http://example.com/" }], + "term" => ["foaf:knows", "ex", { "@id" => "ex" }], + "prefix:suffix" => ["foaf:knows", "ex:suffix", { "@id" => "http://example.org/suffix" }], + "no IRI" => ["foo", "http://example.com/", { "@value" => "http://example.com/" }], + "no term" => ["foo", "ex", { "@value" => "ex" }], + "no prefix" => ["foo", "ex:suffix", { "@value" => "ex:suffix" }], + "integer" => ["foaf:age", "54", { "@value" => "54", "@type" => RDF::XSD.integer.to_s }], + "date " => ["dc:created", "2011-12-27Z", + { "@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s }], + "native boolean" => ["foo", true, { "@value" => true }], + "native integer" => ["foo", 1, { "@value" => 1 }], + "native double" => ["foo", 1.1e1, { "@value" => 1.1E1 }], + "native date" => ["foo", Date.parse("2011-12-27"), + { "@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s }], + "native dateTime" => ["foo", DateTime.parse("2011-12-27T10:11:12Z"), + { "@value" => "2011-12-27T10:11:12Z", "@type" => RDF::XSD.dateTime.to_s }], + "ex:none string" => ["ex:none", "foo", { "@value" => "foo" }], + "ex:none boolean" => ["ex:none", true, { "@value" => true }], + "ex:none integer" => ["ex:none", 1, { "@value" => 1 }], + "ex:none double" => ["ex:none", 1.1e1, { "@value" => 1.1E1 }], + "ex:json string" => ["ex:json", "foo", { "@value" => "foo", "@type" => "@json" }], + "ex:json boolean" => ["ex:json", true, { "@value" => true, "@type" => "@json" }], + "ex:json integer" => ["ex:json", 1, { "@value" => 1, "@type" => "@json" }], + "ex:json double" => ["ex:json", 1.1e1, { "@value" => 1.1e1, "@type" => "@json" }], + "ex:json object" => ["ex:json", { "foo" => "bar" }, + { "@value" => { "foo" => "bar" }, "@type" => "@json" }], + "ex:json array" => ["ex:json", [{ "foo" => "bar" }], + { "@value" => [{ "foo" => "bar" }], "@type" => "@json" }] }.each do |title, (key, compacted, expanded)| it title do expect(subject.expand_value(key, compacted)).to produce(expanded, logger) @@ -1598,14 +1646,16 @@ def containers end context "@language" do - before(:each) {subject.default_language = "en"} + before { subject.default_language = "en" } + { - "no IRI" => ["foo", "http://example.com/", {"@value" => "http://example.com/", "@language" => "en"}], - "no term" => ["foo", "ex", {"@value" => "ex", "@language" => "en"}], - "no prefix" => ["foo", "ex:suffix", {"@value" => "ex:suffix", "@language" => "en"}], - "native boolean" => ["foo", true, {"@value" => true}], - "native integer" => ["foo", 1, {"@value" => 1}], - "native double" => ["foo", 1.1, {"@value" => 1.1}], + "no IRI" => ["foo", "http://example.com/", + { "@value" => "http://example.com/", "@language" => "en" }], + "no term" => ["foo", "ex", { "@value" => "ex", "@language" => "en" }], + "no prefix" => ["foo", "ex:suffix", { "@value" => "ex:suffix", "@language" => "en" }], + "native boolean" => ["foo", true, { "@value" => true }], + "native integer" => ["foo", 1, { "@value" => 1 }], + "native double" => ["foo", 1.1, { "@value" => 1.1 }] }.each do |title, (key, compacted, expanded)| it title do expect(subject.expand_value(key, compacted)).to produce(expanded, logger) @@ -1614,25 +1664,26 @@ def containers end context "coercion" do - before(:each) {subject.default_language = "en"} + before { subject.default_language = "en" } + { - "boolean-boolean" => ["ex:boolean", true, {"@value" => true, "@type" => RDF::XSD.boolean.to_s}], - "boolean-integer" => ["ex:integer", true, {"@value" => true, "@type" => RDF::XSD.integer.to_s}], - "boolean-double" => ["ex:double", true, {"@value" => true, "@type" => RDF::XSD.double.to_s}], - "boolean-json" => ["ex:json", true, {"@value" => true, "@type" => '@json'}], - "double-boolean" => ["ex:boolean", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.boolean.to_s}], - "double-double" => ["ex:double", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.double.to_s}], - "double-integer" => ["foaf:age", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.integer.to_s}], - "double-json" => ["ex:json", 1.1, {"@value" => 1.1, "@type" => '@json'}], - "json-json" => ["ex:json", {"foo" => "bar"}, {"@value" => {"foo" => "bar"}, "@type" => '@json'}], - "integer-boolean" => ["ex:boolean", 1, {"@value" => 1, "@type" => RDF::XSD.boolean.to_s}], - "integer-double" => ["ex:double", 1, {"@value" => 1, "@type" => RDF::XSD.double.to_s}], - "integer-integer" => ["foaf:age", 1, {"@value" => 1, "@type" => RDF::XSD.integer.to_s}], - "integer-json" => ["ex:json", 1, {"@value" => 1, "@type" => '@json'}], - "string-boolean" => ["ex:boolean", "foo", {"@value" => "foo", "@type" => RDF::XSD.boolean.to_s}], - "string-double" => ["ex:double", "foo", {"@value" => "foo", "@type" => RDF::XSD.double.to_s}], - "string-integer" => ["foaf:age", "foo", {"@value" => "foo", "@type" => RDF::XSD.integer.to_s}], - "string-json" => ["ex:json", "foo", {"@value" => "foo", "@type" => '@json'}], + "boolean-boolean" => ["ex:boolean", true, { "@value" => true, "@type" => RDF::XSD.boolean.to_s }], + "boolean-integer" => ["ex:integer", true, { "@value" => true, "@type" => RDF::XSD.integer.to_s }], + "boolean-double" => ["ex:double", true, { "@value" => true, "@type" => RDF::XSD.double.to_s }], + "boolean-json" => ["ex:json", true, { "@value" => true, "@type" => '@json' }], + "double-boolean" => ["ex:boolean", 1.1, { "@value" => 1.1, "@type" => RDF::XSD.boolean.to_s }], + "double-double" => ["ex:double", 1.1, { "@value" => 1.1, "@type" => RDF::XSD.double.to_s }], + "double-integer" => ["foaf:age", 1.1, { "@value" => 1.1, "@type" => RDF::XSD.integer.to_s }], + "double-json" => ["ex:json", 1.1, { "@value" => 1.1, "@type" => '@json' }], + "json-json" => ["ex:json", { "foo" => "bar" }, { "@value" => { "foo" => "bar" }, "@type" => '@json' }], + "integer-boolean" => ["ex:boolean", 1, { "@value" => 1, "@type" => RDF::XSD.boolean.to_s }], + "integer-double" => ["ex:double", 1, { "@value" => 1, "@type" => RDF::XSD.double.to_s }], + "integer-integer" => ["foaf:age", 1, { "@value" => 1, "@type" => RDF::XSD.integer.to_s }], + "integer-json" => ["ex:json", 1, { "@value" => 1, "@type" => '@json' }], + "string-boolean" => ["ex:boolean", "foo", { "@value" => "foo", "@type" => RDF::XSD.boolean.to_s }], + "string-double" => ["ex:double", "foo", { "@value" => "foo", "@type" => RDF::XSD.double.to_s }], + "string-integer" => ["foaf:age", "foo", { "@value" => "foo", "@type" => RDF::XSD.integer.to_s }], + "string-json" => ["ex:json", "foo", { "@value" => "foo", "@type" => '@json' }] }.each do |title, (key, compacted, expanded)| it title do expect(subject.expand_value(key, compacted)).to produce(expanded, logger) @@ -1642,44 +1693,51 @@ def containers end describe "#compact_value" do + subject { ctx } + let(:ctx) do c = context.parse({ - "dc" => RDF::Vocab::DC.to_uri.to_s, - "ex" => "http://example.org/", - "foaf" => RDF::Vocab::FOAF.to_uri.to_s, - "xsd" => RDF::XSD.to_s, - "langmap" => {"@id" => "http://example.com/langmap", "@container" => "@language"}, - "list" => {"@id" => "http://example.org/list", "@container" => "@list"}, - "nolang" => {"@id" => "http://example.org/nolang", "@language" => nil}, - "dc:created" => {"@type" => RDF::XSD.date.to_s}, - "foaf:age" => {"@type" => RDF::XSD.integer.to_s}, - "foaf:knows" => {"@type" => "@id"}, - "ex:none" => {"@type" => "@none"}, + "dc" => RDF::Vocab::DC.to_uri.to_s, + "ex" => "http://example.org/", + "foaf" => RDF::Vocab::FOAF.to_uri.to_s, + "xsd" => RDF::XSD.to_s, + "langmap" => { "@id" => "http://example.com/langmap", "@container" => "@language" }, + "list" => { "@id" => "http://example.org/list", "@container" => "@list" }, + "nolang" => { "@id" => "http://example.org/nolang", "@language" => nil }, + "dc:created" => { "@type" => RDF::XSD.date.to_s }, + "foaf:age" => { "@type" => RDF::XSD.integer.to_s }, + "foaf:knows" => { "@type" => "@id" }, + "ex:none" => { "@type" => "@none" } }) logger.clear c end - subject {ctx} { - "absolute IRI" => ["foaf:knows", "http://example.com/", {"@id" => "http://example.com/"}], - "prefix:suffix" => ["foaf:knows", "ex:suffix", {"@id" => "http://example.org/suffix"}], - "integer" => ["foaf:age", "54", {"@value" => "54", "@type" => RDF::XSD.integer.to_s}], - "date " => ["dc:created", "2011-12-27Z", {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}], - "no IRI" => ["foo", {"@id" =>"http://example.com/"},{"@id" => "http://example.com/"}], - "no IRI (Compact IRI)" => ["foo", {"@id" => RDF::Vocab::FOAF.Person.to_s}, {"@id" => RDF::Vocab::FOAF.Person.to_s}], - "no boolean" => ["foo", {"@value" => "true", "@type" => "xsd:boolean"},{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}], - "no integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"},{"@value" => "54", "@type" => RDF::XSD.integer.to_s}], - "no date " => ["foo", {"@value" => "2011-12-27Z", "@type" => "xsd:date"}, {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}], - "no string " => ["foo", "string", {"@value" => "string"}], - "no lang " => ["nolang", "string", {"@value" => "string"}], - "native boolean" => ["foo", true, {"@value" => true}], - "native integer" => ["foo", 1, {"@value" => 1}], - "native integer(list)"=>["list", 1, {"@value" => 1}], - "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}], - "ex:none IRI" => ["ex:none", {"@id" => "http://example.com/"}, {"@id" => "http://example.com/"}], - "ex:none string" => ["ex:none", {"@value" => "string"}, {"@value" => "string"}], - "ex:none integer" =>["ex:none", {"@value" => "54", "@type" => "xsd:integer"}, {"@value" => "54", "@type" => RDF::XSD.integer.to_s}], + "absolute IRI" => ["foaf:knows", "http://example.com/", { "@id" => "http://example.com/" }], + "prefix:suffix" => ["foaf:knows", "ex:suffix", { "@id" => "http://example.org/suffix" }], + "integer" => ["foaf:age", "54", { "@value" => "54", "@type" => RDF::XSD.integer.to_s }], + "date " => ["dc:created", "2011-12-27Z", + { "@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s }], + "no IRI" => ["foo", { "@id" => "http://example.com/" }, { "@id" => "http://example.com/" }], + "no IRI (Compact IRI)" => ["foo", { "@id" => RDF::Vocab::FOAF.Person.to_s }, + { "@id" => RDF::Vocab::FOAF.Person.to_s }], + "no boolean" => ["foo", { "@value" => "true", "@type" => "xsd:boolean" }, + { "@value" => "true", "@type" => RDF::XSD.boolean.to_s }], + "no integer" => ["foo", { "@value" => "54", "@type" => "xsd:integer" }, + { "@value" => "54", "@type" => RDF::XSD.integer.to_s }], + "no date " => ["foo", { "@value" => "2011-12-27Z", "@type" => "xsd:date" }, + { "@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s }], + "no string " => ["foo", "string", { "@value" => "string" }], + "no lang " => ["nolang", "string", { "@value" => "string" }], + "native boolean" => ["foo", true, { "@value" => true }], + "native integer" => ["foo", 1, { "@value" => 1 }], + "native integer(list)" => ["list", 1, { "@value" => 1 }], + "native double" => ["foo", 1.1e1, { "@value" => 1.1E1 }], + "ex:none IRI" => ["ex:none", { "@id" => "http://example.com/" }, { "@id" => "http://example.com/" }], + "ex:none string" => ["ex:none", { "@value" => "string" }, { "@value" => "string" }], + "ex:none integer" => ["ex:none", { "@value" => "54", "@type" => "xsd:integer" }, + { "@value" => "54", "@type" => RDF::XSD.integer.to_s }] }.each do |title, (key, compacted, expanded)| it title do expect(subject.compact_value(key, expanded)).to produce(compacted, logger) @@ -1688,24 +1746,39 @@ def containers context "@language" do { - "@id" => ["foo", {"@id" => "foo"}, {"@id" => "foo"}], - "integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"}, {"@value" => "54", "@type" => RDF::XSD.integer.to_s}], - "date" => ["foo", {"@value" => "2011-12-27Z","@type" => "xsd:date"},{"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}], - "no lang" => ["foo", {"@value" => "foo" }, {"@value" => "foo"}], - "same lang" => ["foo", "foo", {"@value" => "foo", "@language" => "en"}], - "other lang" => ["foo", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}], - "langmap" => ["langmap", "en", {"@value" => "en", "@language" => "en"}], - "no lang with @type coercion" => ["dc:created", {"@value" => "foo"}, {"@value" => "foo"}], - "no lang with @id coercion" => ["foaf:knows", {"@value" => "foo"}, {"@value" => "foo"}], - "no lang with @language=null" => ["nolang", "string", {"@value" => "string"}], - "same lang with @type coercion" => ["dc:created", {"@value" => "foo"}, {"@value" => "foo"}], - "same lang with @id coercion" => ["foaf:knows", {"@value" => "foo"}, {"@value" => "foo"}], - "other lang with @type coercion" => ["dc:created", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}], - "other lang with @id coercion" => ["foaf:knows", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}], - "native boolean" => ["foo", true, {"@value" => true}], - "native integer" => ["foo", 1, {"@value" => 1}], - "native integer(list)" => ["list", 1, {"@value" => 1}], - "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}], + "@id" => ["foo", { "@id" => "foo" }, { "@id" => "foo" }], + "integer" => ["foo", { "@value" => "54", "@type" => "xsd:integer" }, + { "@value" => "54", "@type" => RDF::XSD.integer.to_s }], + "date" => ["foo", { "@value" => "2011-12-27Z", "@type" => "xsd:date" }, + { "@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s }], + "no lang" => ["foo", { "@value" => "foo" }, + { "@value" => "foo" }], + "same lang" => ["foo", "foo", + { "@value" => "foo", "@language" => "en" }], + "other lang" => ["foo", { "@value" => "foo", "@language" => "bar" }, + { "@value" => "foo", "@language" => "bar" }], + "langmap" => ["langmap", "en", + { "@value" => "en", "@language" => "en" }], + "no lang with @type coercion" => ["dc:created", { "@value" => "foo" }, + { "@value" => "foo" }], + "no lang with @id coercion" => ["foaf:knows", { "@value" => "foo" }, + { "@value" => "foo" }], + "no lang with @language=null" => ["nolang", "string", + { "@value" => "string" }], + "same lang with @type coercion" => ["dc:created", { "@value" => "foo" }, + { "@value" => "foo" }], + "same lang with @id coercion" => ["foaf:knows", { "@value" => "foo" }, + { "@value" => "foo" }], + "other lang with @type coercion" => ["dc:created", { "@value" => "foo", "@language" => "bar" }, + { "@value" => "foo", "@language" => "bar" }], + "other lang with @id coercion" => ["foaf:knows", { "@value" => "foo", "@language" => "bar" }, + { "@value" => "foo", "@language" => "bar" }], + "native boolean" => ["foo", true, + { "@value" => true }], + "native integer" => ["foo", 1, { "@value" => 1 }], + "native integer(list)" => ["list", 1, { "@value" => 1 }], + "native double" => ["foo", 1.1e1, + { "@value" => 1.1E1 }] }.each do |title, (key, compacted, expanded)| it title do subject.default_language = "en" @@ -1715,7 +1788,7 @@ def containers end context "keywords" do - before(:each) do + before do subject.set_mapping("id", "@id") subject.set_mapping("type", "@type") subject.set_mapping("list", "@list") @@ -1725,10 +1798,10 @@ def containers end { - "@id" => [{"id" => "http://example.com/"}, {"@id" => "http://example.com/"}], - "@type" => [{"literal" => "foo", "type" => "http://example.com/"}, - {"@value" => "foo", "@type" => "http://example.com/"}], - "@value" => [{"literal" => "foo", "language" => "bar"}, {"@value" => "foo", "@language" => "bar"}], + "@id" => [{ "id" => "http://example.com/" }, { "@id" => "http://example.com/" }], + "@type" => [{ "literal" => "foo", "type" => "http://example.com/" }, + { "@value" => "foo", "@type" => "http://example.com/" }], + "@value" => [{ "literal" => "foo", "language" => "bar" }, { "@value" => "foo", "@language" => "bar" }] }.each do |title, (compacted, expanded)| it title do expect(subject.compact_value("foo", expanded)).to produce(compacted, logger) @@ -1742,49 +1815,49 @@ def containers end describe "#container" do - subject { + subject do ctx = context.parse({ - "ex" => "http://example.org/", - "graph" => {"@id" => "ex:graph", "@container" => "@graph"}, - "graphSet" => {"@id" => "ex:graphSet", "@container" => ["@graph", "@set"]}, - "graphId" => {"@id" => "ex:graphSet", "@container" => ["@graph", "@id"]}, - "graphIdSet" => {"@id" => "ex:graphSet", "@container" => ["@graph", "@id", "@set"]}, - "graphNdx" => {"@id" => "ex:graphSet", "@container" => ["@graph", "@index"]}, - "graphNdxSet" => {"@id" => "ex:graphSet", "@container" => ["@graph", "@index", "@set"]}, - "id" => {"@id" => "ex:idSet", "@container" => "@id"}, - "idSet" => {"@id" => "ex:id", "@container" => ["@id", "@set"]}, - "language" => {"@id" => "ex:language", "@container" => "@language"}, - "langSet" => {"@id" => "ex:languageSet", "@container" => ["@language", "@set"]}, - "list" => {"@id" => "ex:list", "@container" => "@list"}, - "ndx" => {"@id" => "ex:ndx", "@container" => "@index"}, - "ndxSet" => {"@id" => "ex:ndxSet", "@container" => ["@index", "@set"]}, - "set" => {"@id" => "ex:set", "@container" => "@set"}, - "type" => {"@id" => "ex:type", "@container" => "@type"}, - "typeSet" => {"@id" => "ex:typeSet", "@container" => ["@type", "@set"]}, + "ex" => "http://example.org/", + "graph" => { "@id" => "ex:graph", "@container" => "@graph" }, + "graphSet" => { "@id" => "ex:graphSet", "@container" => ["@graph", "@set"] }, + "graphId" => { "@id" => "ex:graphSet", "@container" => ["@graph", "@id"] }, + "graphIdSet" => { "@id" => "ex:graphSet", "@container" => ["@graph", "@id", "@set"] }, + "graphNdx" => { "@id" => "ex:graphSet", "@container" => ["@graph", "@index"] }, + "graphNdxSet" => { "@id" => "ex:graphSet", "@container" => ["@graph", "@index", "@set"] }, + "id" => { "@id" => "ex:idSet", "@container" => "@id" }, + "idSet" => { "@id" => "ex:id", "@container" => ["@id", "@set"] }, + "language" => { "@id" => "ex:language", "@container" => "@language" }, + "langSet" => { "@id" => "ex:languageSet", "@container" => ["@language", "@set"] }, + "list" => { "@id" => "ex:list", "@container" => "@list" }, + "ndx" => { "@id" => "ex:ndx", "@container" => "@index" }, + "ndxSet" => { "@id" => "ex:ndxSet", "@container" => ["@index", "@set"] }, + "set" => { "@id" => "ex:set", "@container" => "@set" }, + "type" => { "@id" => "ex:type", "@container" => "@type" }, + "typeSet" => { "@id" => "ex:typeSet", "@container" => ["@type", "@set"] } }) logger.clear ctx - } + end it "uses TermDefinition" do { - "ex" => Set.new, - "graph" => Set["@graph"], - "graphSet" => Set["@graph"], - "graphId" => Set["@graph", "@id"], - "graphIdSet" => Set["@graph", "@id"], - "graphNdx" => Set["@graph", "@index"], + "ex" => Set.new, + "graph" => Set["@graph"], + "graphSet" => Set["@graph"], + "graphId" => Set["@graph", "@id"], + "graphIdSet" => Set["@graph", "@id"], + "graphNdx" => Set["@graph", "@index"], "graphNdxSet" => Set["@graph", "@index"], - "id" => Set['@id'], - "idSet" => Set['@id'], - "language" => Set['@language'], - "langSet" => Set['@language'], - "list" => Set['@list'], - "ndx" => Set['@index'], - "ndxSet" => Set['@index'], - "set" => Set.new, - "type" => Set['@type'], - "typeSet" => Set['@type'], + "id" => Set['@id'], + "idSet" => Set['@id'], + "language" => Set['@language'], + "langSet" => Set['@language'], + "list" => Set['@list'], + "ndx" => Set['@index'], + "ndxSet" => Set['@index'], + "set" => Set.new, + "type" => Set['@type'], + "typeSet" => Set['@type'] }.each do |defn, container| expect(subject.container(subject.term_definitions[defn])).to eq container end @@ -1792,23 +1865,23 @@ def containers it "#as_array" do { - "ex" => false, - "graph" => false, - "graphSet" => true, - "graphId" => false, - "graphIdSet" => true, - "graphNdx" => false, + "ex" => false, + "graph" => false, + "graphSet" => true, + "graphId" => false, + "graphIdSet" => true, + "graphNdx" => false, "graphNdxSet" => true, - "id" => false, - "idSet" => true, - "language" => false, - "langSet" => true, - "list" => true, - "ndx" => false, - "ndxSet" => true, - "set" => true, - "type" => false, - "typeSet" => true, + "id" => false, + "idSet" => true, + "language" => false, + "langSet" => true, + "list" => true, + "ndx" => false, + "ndxSet" => true, + "set" => true, + "type" => false, + "typeSet" => true }.each do |defn, as_array| expect(subject.as_array?(subject.term_definitions[defn])).to eq as_array end @@ -1816,23 +1889,23 @@ def containers it "uses array" do { - "ex" => Set.new, - "graph" => Set["@graph"], - "graphSet" => Set["@graph"], - "graphId" => Set["@graph", "@id"], - "graphIdSet" => Set["@graph", "@id"], - "graphNdx" => Set["@graph", "@index"], + "ex" => Set.new, + "graph" => Set["@graph"], + "graphSet" => Set["@graph"], + "graphId" => Set["@graph", "@id"], + "graphIdSet" => Set["@graph", "@id"], + "graphNdx" => Set["@graph", "@index"], "graphNdxSet" => Set["@graph", "@index"], - "id" => Set['@id'], - "idSet" => Set['@id'], - "language" => Set['@language'], - "langSet" => Set['@language'], - "list" => Set['@list'], - "ndx" => Set['@index'], - "ndxSet" => Set['@index'], - "set" => Set.new, - "type" => Set['@type'], - "typeSet" => Set['@type'], + "id" => Set['@id'], + "idSet" => Set['@id'], + "language" => Set['@language'], + "langSet" => Set['@language'], + "list" => Set['@list'], + "ndx" => Set['@index'], + "ndxSet" => Set['@index'], + "set" => Set.new, + "type" => Set['@type'], + "typeSet" => Set['@type'] }.each do |defn, container| expect(subject.container(defn)).to eq container end @@ -1840,15 +1913,16 @@ def containers end describe "#language" do - subject { + subject do ctx = context.parse({ "ex" => "http://example.org/", - "nil" => {"@id" => "ex:nil", "@language" => nil}, - "en" => {"@id" => "ex:en", "@language" => "en"}, + "nil" => { "@id" => "ex:nil", "@language" => nil }, + "en" => { "@id" => "ex:en", "@language" => "en" } }) logger.clear ctx - } + end + it "uses TermDefinition" do expect(subject.language(subject.term_definitions['ex'])).to be_falsey expect(subject.language(subject.term_definitions['nil'])).to be_falsey @@ -1863,43 +1937,44 @@ def containers end describe "#reverse?" do - subject { + subject do ctx = context.parse({ "ex" => "http://example.org/", - "reverse" => {"@reverse" => "ex:reverse"}, + "reverse" => { "@reverse" => "ex:reverse" } }) logger.clear ctx - } + end + it "uses TermDefinition" do - expect(subject.reverse?(subject.term_definitions['ex'])).to be_falsey - expect(subject.reverse?(subject.term_definitions['reverse'])).to be_truthy + expect(subject).not_to be_reverse(subject.term_definitions['ex']) + expect(subject).to be_reverse(subject.term_definitions['reverse']) end it "uses string" do - expect(subject.reverse?('ex')).to be_falsey - expect(subject.reverse?('reverse')).to be_truthy + expect(subject).not_to be_reverse('ex') + expect(subject).to be_reverse('reverse') end end describe "#nest" do - subject { + subject do ctx = context.parse({ - "ex" => "http://example.org/", - "nest" => {"@id" => "ex:nest", "@nest" => "@nest"}, - "nest2" => {"@id" => "ex:nest2", "@nest" => "nest-alias"}, - "nest-alias" => "@nest" + "ex" => "http://example.org/", + "nest" => { "@id" => "ex:nest", "@nest" => "@nest" }, + "nest2" => { "@id" => "ex:nest2", "@nest" => "nest-alias" }, + "nest-alias" => "@nest" }) logger.clear ctx - } + end it "uses term" do { - "ex" => nil, - "nest" => "@nest", - "nest2" => "nest-alias", - "nest-alias" => nil, + "ex" => nil, + "nest" => "@nest", + "nest2" => "nest-alias", + "nest-alias" => nil }.each do |defn, nest| expect(subject.nest(defn)).to eq nest end @@ -1907,28 +1982,29 @@ def containers context "detects error" do it "does not allow a keyword other than @nest for the value of @nest" do - expect { - context.parse({"no-keyword-nest" => {"@id" => "http://example/f", "@nest" => "@id"}}) - }.to raise_error JSON::LD::JsonLdError::InvalidNestValue + expect do + context.parse({ "no-keyword-nest" => { "@id" => "http://example/f", "@nest" => "@id" } }) + end.to raise_error JSON::LD::JsonLdError::InvalidNestValue end it "does not allow @nest with @reverse" do - expect { - context.parse({"no-reverse-nest" => {"@reverse" => "http://example/f", "@nest" => "@nest"}}) - }.to raise_error JSON::LD::JsonLdError::InvalidReverseProperty + expect do + context.parse({ "no-reverse-nest" => { "@reverse" => "http://example/f", "@nest" => "@nest" } }) + end.to raise_error JSON::LD::JsonLdError::InvalidReverseProperty end end end describe "#reverse_term" do - subject { + subject do ctx = context.parse({ "ex" => "http://example.org/", - "reverse" => {"@reverse" => "ex"}, + "reverse" => { "@reverse" => "ex" } }) logger.clear ctx - } + end + it "uses TermDefinition" do expect(subject.reverse_term(subject.term_definitions['ex'])).to eql subject.term_definitions['reverse'] expect(subject.reverse_term(subject.term_definitions['reverse'])).to eql subject.term_definitions['ex'] @@ -1943,8 +2019,8 @@ def containers describe "protected contexts" do it "seals a term with @protected true" do ctx = context.parse({ - "protected" => {"@id" => "http://example.com/protected", "@protected" => true}, - "unprotected" => {"@id" => "http://example.com/unprotected"}, + "protected" => { "@id" => "http://example.com/protected", "@protected" => true }, + "unprotected" => { "@id" => "http://example.com/unprotected" } }) expect(ctx.term_definitions["protected"]).to be_protected expect(ctx.term_definitions["unprotected"]).not_to be_protected @@ -1953,8 +2029,8 @@ def containers it "seals all term with @protected true in context" do ctx = context.parse({ "@protected" => true, - "protected" => {"@id" => "http://example.com/protected"}, - "protected2" => {"@id" => "http://example.com/protected2"}, + "protected" => { "@id" => "http://example.com/protected" }, + "protected2" => { "@id" => "http://example.com/protected2" } }) expect(ctx.term_definitions["protected"]).to be_protected expect(ctx.term_definitions["protected2"]).to be_protected @@ -1963,8 +2039,8 @@ def containers it "does not seal term with @protected: false when context is protected" do ctx = context.parse({ "@protected" => true, - "protected" => {"@id" => "http://example.com/protected"}, - "unprotected" => {"@id" => "http://example.com/unprotected", "@protected" => false}, + "protected" => { "@id" => "http://example.com/protected" }, + "unprotected" => { "@id" => "http://example.com/unprotected", "@protected" => false } }) expect(ctx.term_definitions["protected"]).to be_protected expect(ctx.term_definitions["unprotected"]).not_to be_protected @@ -1972,85 +2048,96 @@ def containers it "does not error when redefining an identical term" do c = { - "protected" => {"@id" => "http://example.com/protected", "@protected" => true} + "protected" => { "@id" => "http://example.com/protected", "@protected" => true } } ctx = context.parse(c) - expect {ctx.parse(c)}.not_to raise_error + expect { ctx.parse(c) }.not_to raise_error end it "errors when redefining a protected term" do ctx = context.parse({ - "protected" => {"@id" => "http://example.com/protected", "@protected" => true} + "protected" => { "@id" => "http://example.com/protected", "@protected" => true } }) - expect {ctx.parse({"protected" => "http://example.com/different"})}.to raise_error(JSON::LD::JsonLdError::ProtectedTermRedefinition) + expect do + ctx.parse({ "protected" => "http://example.com/different" }) + end.to raise_error(JSON::LD::JsonLdError::ProtectedTermRedefinition) end it "errors when clearing a context having protected terms" do ctx = context.parse({ - "protected" => {"@id" => "http://example.com/protected", "@protected" => true} + "protected" => { "@id" => "http://example.com/protected", "@protected" => true } }) - expect {ctx.parse(nil)}.to raise_error(JSON::LD::JsonLdError::InvalidContextNullification) + expect { ctx.parse(nil) }.to raise_error(JSON::LD::JsonLdError::InvalidContextNullification) end end describe JSON::LD::Context::TermDefinition do context "with nothing" do - subject {described_class.new("term")} - its(:term) {is_expected.to eq "term"} - its(:id) {is_expected.to be_nil} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term"))} + subject { described_class.new("term") } + + its(:term) { is_expected.to eq "term" } + its(:id) { is_expected.to be_nil } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term")) } end context "with id" do - subject {described_class.new("term", id: "http://example.org/term")} - its(:term) {is_expected.to eq "term"} - its(:id) {is_expected.to eq "http://example.org/term"} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", id: "http://example.org/term"))} + subject { described_class.new("term", id: "http://example.org/term") } + + its(:term) { is_expected.to eq "term" } + its(:id) { is_expected.to eq "http://example.org/term" } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", id: "http://example.org/term")) } end context "with type_mapping" do - subject {described_class.new("term", type_mapping: "http://example.org/type")} - its(:type_mapping) {is_expected.to eq "http://example.org/type"} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", type_mapping: "http://example.org/type"))} + subject { described_class.new("term", type_mapping: "http://example.org/type") } + + its(:type_mapping) { is_expected.to eq "http://example.org/type" } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", type_mapping: "http://example.org/type")) } end context "with container_mapping @set" do - subject {described_class.new("term", container_mapping: "@set")} - its(:container_mapping) {is_expected.to be_empty} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", container_mapping: "@set"))} + subject { described_class.new("term", container_mapping: "@set") } + + its(:container_mapping) { is_expected.to be_empty } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", container_mapping: "@set")) } end context "with container_mapping @id @set" do - subject {described_class.new("term", container_mapping: %w(@id @set))} - its(:container_mapping) {is_expected.to eq Set['@id']} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", container_mapping: ["@id", "@set"]))} + subject { described_class.new("term", container_mapping: %w[@id @set]) } + + its(:container_mapping) { is_expected.to eq Set['@id'] } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", container_mapping: ["@id", "@set"])) } end context "with container_mapping @list" do - subject {described_class.new("term", container_mapping: "@list")} - its(:container_mapping) {is_expected.to eq Set['@list']} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", container_mapping: "@list"))} + subject { described_class.new("term", container_mapping: "@list") } + + its(:container_mapping) { is_expected.to eq Set['@list'] } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", container_mapping: "@list")) } end context "with language_mapping" do - subject {described_class.new("term", language_mapping: "en")} - its(:language_mapping) {is_expected.to eq "en"} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", language_mapping: "en"))} + subject { described_class.new("term", language_mapping: "en") } + + its(:language_mapping) { is_expected.to eq "en" } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", language_mapping: "en")) } end context "with reverse_property" do - subject {described_class.new("term", reverse_property: true)} - its(:reverse_property) {is_expected.to be_truthy} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", reverse_property: true))} + subject { described_class.new("term", reverse_property: true) } + + its(:reverse_property) { is_expected.to be_truthy } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", reverse_property: true)) } end context "with simple" do - subject {described_class.new("term", simple: true)} - its(:simple) {is_expected.to be_truthy} - its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", simple: true))} + subject { described_class.new("term", simple: true) } + + its(:simple) { is_expected.to be_truthy } + its(:to_rb) { is_expected.to eq %(TermDefinition.new("term", simple: true)) } end end end diff --git a/spec/expand_spec.rb b/spec/expand_spec.rb index ccd4473e..d9f2b785 100644 --- a/spec/expand_spec.rb +++ b/spec/expand_spec.rb @@ -1,16 +1,17 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } describe ".expand" do { - "empty doc": { + 'empty doc': { input: {}, output: [] }, - "@list coercion": { + '@list coercion': { input: %({ "@context": { "foo": {"@id": "http://example.com/foo", "@container": "@list"} @@ -21,7 +22,7 @@ "http://example.com/foo": [{"@list": [{"@value": "bar"}]}] }]) }, - "native values in list": { + 'native values in list': { input: %({ "http://example.com/foo": {"@list": [1, 2]} }), @@ -29,7 +30,7 @@ "http://example.com/foo": [{"@list": [{"@value": 1}, {"@value": 2}]}] }]) }, - "@graph": { + '@graph': { input: %({ "@context": {"ex": "http://example.com/"}, "@graph": [ @@ -42,7 +43,7 @@ {"http://example.com/bar": [{"@value": "bar"}]} ]) }, - "@graph value (expands to array form)": { + '@graph value (expands to array form)': { input: %({ "@context": {"ex": "http://example.com/"}, "ex:p": { @@ -61,7 +62,7 @@ }] }]) }, - "@type with CURIE": { + '@type with CURIE': { input: %({ "@context": {"ex": "http://example.com/"}, "@type": "ex:type" @@ -70,7 +71,7 @@ {"@type": ["http://example.com/type"]} ]) }, - "@type with CURIE and muliple values": { + '@type with CURIE and muliple values': { input: %({ "@context": {"ex": "http://example.com/"}, "@type": ["ex:type1", "ex:type2"] @@ -79,11 +80,11 @@ {"@type": ["http://example.com/type1", "http://example.com/type2"]} ]) }, - "@value with false": { + '@value with false': { input: %({"http://example.com/ex": {"@value": false}}), output: %([{"http://example.com/ex": [{"@value": false}]}]) }, - "compact IRI": { + 'compact IRI': { input: %({ "@context": {"ex": "http://example.com/"}, "ex:p": {"@id": "ex:Sub1"} @@ -91,14 +92,14 @@ output: %([{ "http://example.com/p": [{"@id": "http://example.com/Sub1"}] }]) - }, + } }.each_pair do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end context "default language" do { - "base": { + base: { input: %({ "http://example/foo": "bar" }), @@ -107,7 +108,7 @@ }]), language: "en" }, - "override": { + override: { input: %({ "@context": {"@language": null}, "http://example/foo": "bar" @@ -118,13 +119,13 @@ language: "en" } }.each_pair do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "with relative IRIs" do { - "base": { + base: { input: %({ "@id": "", "@type": "http://www.w3.org/2000/01/rdf-schema#Resource" @@ -134,7 +135,7 @@ "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"] }]) }, - "relative": { + relative: { input: %({ "@id": "a/b", "@type": "http://www.w3.org/2000/01/rdf-schema#Resource" @@ -144,7 +145,7 @@ "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"] }]) }, - "hash": { + hash: { input: %({ "@id": "#a", "@type": "http://www.w3.org/2000/01/rdf-schema#Resource" @@ -154,7 +155,7 @@ "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"] }]) }, - "unmapped @id": { + 'unmapped @id': { input: %({ "http://example.com/foo": {"@id": "bar"} }), @@ -162,7 +163,7 @@ "http://example.com/foo": [{"@id": "http://example.org/bar"}] }]) }, - "json-ld-syntax#66": { + 'json-ld-syntax#66': { input: %({ "@context": { "@base": "https://ex.org/", @@ -178,13 +179,13 @@ }]) } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example.org/")} + it(title) { run_expand params.merge(base: "http://example.org/") } end end context "with relative property IRIs" do { - "base": { + base: { input: %({ "http://a/b": "foo" }), @@ -192,31 +193,31 @@ "http://a/b": [{"@value": "foo"}] }]) }, - "relative": { + relative: { input: %({ "a/b": "foo" }), output: %([]) }, - "hash": { + hash: { input: %({ "#a": "foo" }), output: %([]) }, - "dotseg": { + dotseg: { input: %({ "../a": "foo" }), output: %([]) - }, + } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example.org/")} + it(title) { run_expand params.merge(base: "http://example.org/") } end context "with @vocab" do { - "base": { + base: { input: %({ "@context": {"@vocab": "http://vocab/"}, "http://a/b": "foo" @@ -225,7 +226,7 @@ "http://a/b": [{"@value": "foo"}] }]) }, - "relative": { + relative: { input: %({ "@context": {"@vocab": "http://vocab/"}, "a/b": "foo" @@ -234,7 +235,7 @@ "http://vocab/a/b": [{"@value": "foo"}] }]) }, - "hash": { + hash: { input: %({ "@context": {"@vocab": "http://vocab/"}, "#a": "foo" @@ -243,7 +244,7 @@ "http://vocab/#a": [{"@value": "foo"}] }]) }, - "dotseg": { + dotseg: { input: %({ "@context": {"@vocab": "http://vocab/"}, "../a": "foo" @@ -251,15 +252,15 @@ output: %([{ "http://vocab/../a": [{"@value": "foo"}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example.org/")} + it(title) { run_expand params.merge(base: "http://example.org/") } end end context "with @vocab: ''" do { - "base": { + base: { input: %({ "@context": {"@vocab": ""}, "http://a/b": "foo" @@ -268,7 +269,7 @@ "http://a/b": [{"@value": "foo"}] }]) }, - "relative": { + relative: { input: %({ "@context": {"@vocab": ""}, "a/b": "foo" @@ -277,7 +278,7 @@ "http://example.org/a/b": [{"@value": "foo"}] }]) }, - "hash": { + hash: { input: %({ "@context": {"@vocab": ""}, "#a": "foo" @@ -286,7 +287,7 @@ "http://example.org/#a": [{"@value": "foo"}] }]) }, - "dotseg": { + dotseg: { input: %({ "@context": {"@vocab": ""}, "../a": "foo" @@ -295,7 +296,7 @@ "http://example.org/../a": [{"@value": "foo"}] }]) }, - "example": { + example: { input: %({ "@context": { "@base": "http://example/document", @@ -312,13 +313,13 @@ }]) } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example.org/")} + it(title) { run_expand params.merge(base: "http://example.org/") } end end context "with @vocab: '/relative#'" do { - "base": { + base: { input: %({ "@context": {"@vocab": "/relative#"}, "http://a/b": "foo" @@ -327,7 +328,7 @@ "http://a/b": [{"@value": "foo"}] }]) }, - "relative": { + relative: { input: %({ "@context": {"@vocab": "/relative#"}, "a/b": "foo" @@ -336,7 +337,7 @@ "http://example.org/relative#a/b": [{"@value": "foo"}] }]) }, - "hash": { + hash: { input: %({ "@context": {"@vocab": "/relative#"}, "#a": "foo" @@ -345,7 +346,7 @@ "http://example.org/relative##a": [{"@value": "foo"}] }]) }, - "dotseg": { + dotseg: { input: %({ "@context": {"@vocab": "/relative#"}, "../a": "foo" @@ -354,7 +355,7 @@ "http://example.org/relative#../a": [{"@value": "foo"}] }]) }, - "example": { + example: { input: %({ "@context": { "@base": "http://example/document", @@ -371,14 +372,14 @@ }]) } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example.org/")} + it(title) { run_expand params.merge(base: "http://example.org/") } end end end context "keyword aliasing" do { - "@id": { + '@id': { input: %({ "@context": {"id": "@id"}, "id": "", @@ -389,7 +390,7 @@ "@type":[ "http://www.w3.org/2000/01/rdf-schema#Resource"] }]) }, - "@type": { + '@type': { input: %({ "@context": {"type": "@type"}, "type": "http://www.w3.org/2000/01/rdf-schema#Resource", @@ -400,7 +401,7 @@ "http://example.com/foo": [{"@value": "bar", "@type": "http://example.com/baz"}] }]) }, - "@language": { + '@language': { input: %({ "@context": {"language": "@language"}, "http://example.com/foo": {"@value": "bar", "language": "baz"} @@ -409,7 +410,7 @@ "http://example.com/foo": [{"@value": "bar", "@language": "baz"}] }]) }, - "@value": { + '@value': { input: %({ "@context": {"literal": "@value"}, "http://example.com/foo": {"literal": "bar"} @@ -418,7 +419,7 @@ "http://example.com/foo": [{"@value": "bar"}] }]) }, - "@list": { + '@list': { input: %({ "@context": {"list": "@list"}, "http://example.com/foo": {"list": ["bar"]} @@ -426,15 +427,15 @@ output: %([{ "http://example.com/foo": [{"@list": [{"@value": "bar"}]}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "native types" do { - "true": { + true => { input: %({ "@context": {"e": "http://example.org/vocab#"}, "e:bool": true @@ -443,7 +444,7 @@ "http://example.org/vocab#bool": [{"@value": true}] }]) }, - "false": { + false => { input: %({ "@context": {"e": "http://example.org/vocab#"}, "e:bool": false @@ -452,7 +453,7 @@ "http://example.org/vocab#bool": [{"@value": false}] }]) }, - "double": { + double: { input: %({ "@context": {"e": "http://example.org/vocab#"}, "e:double": 1.23 @@ -461,7 +462,7 @@ "http://example.org/vocab#double": [{"@value": 1.23}] }]) }, - "double-zero": { + 'double-zero': { input: %({ "@context": {"e": "http://example.org/vocab#"}, "e:double-zero": 0.0e0 @@ -470,7 +471,7 @@ "http://example.org/vocab#double-zero": [{"@value": 0.0e0}] }]) }, - "integer": { + integer: { input: %({ "@context": {"e": "http://example.org/vocab#"}, "e:integer": 123 @@ -478,23 +479,23 @@ output: %([{ "http://example.org/vocab#integer": [{"@value": 123}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end context "with @type: @none" do { - "true": { + true => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}}, "e": true }), - output:%( [{ + output: %( [{ "http://example.org/vocab#bool": [{"@value": true}] }]) }, - "false": { + false => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}}, "e": false @@ -503,7 +504,7 @@ "http://example.org/vocab#bool": [{"@value": false}] }]) }, - "double": { + double: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}}, "e": 1.23 @@ -512,7 +513,7 @@ "http://example.org/vocab#double": [{"@value": 1.23}] }]) }, - "double-zero": { + 'double-zero': { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}}, "e": 0.0e0 @@ -521,7 +522,7 @@ "http://example.org/vocab#double": [{"@value": 0.0e0}] }]) }, - "integer": { + integer: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@none"}}, "e": 123 @@ -529,24 +530,24 @@ output: %([{ "http://example.org/vocab#integer": [{"@value": 123}] }]) - }, + } }.each do |title, params| - it(title) {run_expand(processingMode: "json-ld-1.1", **params)} + it(title) { run_expand(processingMode: "json-ld-1.1", **params) } end end context "with @type: @id" do { - "true": { + true => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@id"}}, "e": true }), - output:%( [{ + output: %( [{ "http://example.org/vocab#bool": [{"@value": true}] }]) }, - "false": { + false => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@id"}}, "e": false @@ -555,7 +556,7 @@ "http://example.org/vocab#bool": [{"@value": false}] }]) }, - "double": { + double: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@id"}}, "e": 1.23 @@ -564,7 +565,7 @@ "http://example.org/vocab#double": [{"@value": 1.23}] }]) }, - "double-zero": { + 'double-zero': { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@id"}}, "e": 0.0e0 @@ -573,7 +574,7 @@ "http://example.org/vocab#double": [{"@value": 0.0e0}] }]) }, - "integer": { + integer: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@id"}}, "e": 123 @@ -581,24 +582,24 @@ output: %([{ "http://example.org/vocab#integer": [{"@value": 123}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "with @type: @vocab" do { - "true": { + true => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@vocab"}}, "e": true }), - output:%( [{ + output: %( [{ "http://example.org/vocab#bool": [{"@value": true}] }]) }, - "false": { + false => { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@vocab"}}, "e": false @@ -607,7 +608,7 @@ "http://example.org/vocab#bool": [{"@value": false}] }]) }, - "double": { + double: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@vocab"}}, "e": 1.23 @@ -616,7 +617,7 @@ "http://example.org/vocab#double": [{"@value": 1.23}] }]) }, - "double-zero": { + 'double-zero': { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@vocab"}}, "e": 0.0e0 @@ -625,7 +626,7 @@ "http://example.org/vocab#double": [{"@value": 0.0e0}] }]) }, - "integer": { + integer: { input: %({ "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@vocab"}}, "e": 123 @@ -633,16 +634,16 @@ output: %([{ "http://example.org/vocab#integer": [{"@value": 123}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end end context "with @type: @json" do { - "true": { + true => { input: %({ "@context": { "@version": 1.1, @@ -650,11 +651,11 @@ }, "e": true }), - output:%( [{ + output: %( [{ "http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}] }]) }, - "false": { + false => { input: %({ "@context": { "@version": 1.1, @@ -666,7 +667,7 @@ "http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}] }]) }, - "double": { + double: { input: %({ "@context": { "@version": 1.1, @@ -678,7 +679,7 @@ "http://example.org/vocab#double": [{"@value": 1.23, "@type": "@json"}] }]) }, - "double-zero": { + 'double-zero': { input: %({ "@context": { "@version": 1.1, @@ -690,7 +691,7 @@ "http://example.org/vocab#double": [{"@value": 0.0e0, "@type": "@json"}] }]) }, - "integer": { + integer: { input: %({ "@context": { "@version": 1.1, @@ -702,7 +703,7 @@ "http://example.org/vocab#integer": [{"@value": 123, "@type": "@json"}] }]) }, - "string": { + string: { input: %({ "@context": { "@version": 1.1, @@ -717,7 +718,7 @@ }] }]) }, - "null": { + null: { input: %({ "@context": { "@version": 1.1, @@ -732,7 +733,7 @@ }] }]) }, - "object": { + object: { input: %({ "@context": { "@version": 1.1, @@ -744,7 +745,7 @@ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] }]) }, - "array": { + array: { input: %({ "@context": { "@version": 1.1, @@ -756,7 +757,7 @@ "http://example.org/vocab#array": [{"@value": [{"foo": "bar"}], "@type": "@json"}] }]) }, - "Does not expand terms inside json": { + 'Does not expand terms inside json': { input: %({ "@context": { "@version": 1.1, @@ -768,7 +769,7 @@ "http://example.org/vocab#array": [{"@value": [{"e": "bar"}], "@type": "@json"}] }]) }, - "Already expanded object": { + 'Already expanded object': { input: %({ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] }), @@ -777,7 +778,7 @@ }]), processingMode: 'json-ld-1.1' }, - "Already expanded object with aliased keys": { + 'Already expanded object with aliased keys': { input: %({ "@context": {"@version": 1.1, "value": "@value", "type": "@type", "json": "@json"}, "http://example.org/vocab#object": [{"value": {"foo": "bar"}, "type": "json"}] @@ -785,15 +786,15 @@ output: %([{ "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "coerced typed values" do { - "boolean": { + boolean: { input: %({ "@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}}, "foo": "true" @@ -802,7 +803,7 @@ "http://example.org/foo": [{"@value": "true", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}] }]) }, - "date": { + date: { input: %({ "@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#date"}}, "foo": "2011-03-26" @@ -810,35 +811,35 @@ output: %([{ "http://example.org/foo": [{"@value": "2011-03-26", "@type": "http://www.w3.org/2001/XMLSchema#date"}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "null" do { - "value": { + value: { input: %({"http://example.com/foo": null}), output: [] }, - "@value": { + '@value': { input: %({"http://example.com/foo": {"@value": null}}), output: [] }, - "@value and non-null @type": { + '@value and non-null @type': { input: %({"http://example.com/foo": {"@value": null, "@type": "http://type"}}), output: [] }, - "@value and non-null @language": { + '@value and non-null @language': { input: %({"http://example.com/foo": {"@value": null, "@language": "en"}}), output: [] }, - "array with null elements": { + 'array with null elements': { input: %({"http://example.com/foo": [null]}), output: %([{"http://example.com/foo": []}]) }, - "@set with null @value": { + '@set with null @value': { input: %({ "http://example.com/foo": [ {"@value": null, "@type": "http://example.org/Type"} @@ -849,13 +850,13 @@ }]) } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "@direction" do { - "value with coerced null direction": { + 'value with coerced null direction': { input: %({ "@context": { "@direction": "rtl", @@ -876,13 +877,13 @@ ]) } }.each_pair do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "default language" do { - "value with coerced null language": { + 'value with coerced null language': { input: %({ "@context": { "@language": "en", @@ -899,14 +900,14 @@ "http://example.org/vocab#nolang": [{"@value": "no language"}] } ]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end context "and default direction" do { - "value with coerced null direction": { + 'value with coerced null direction': { input: %({ "@context": { "@language": "en", @@ -946,14 +947,14 @@ ]) } }.each_pair do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end end context "default vocabulary" do { - "property": { + property: { input: %({ "@context": {"@vocab": "http://example.com/"}, "verb": {"@value": "foo"} @@ -962,7 +963,7 @@ "http://example.com/verb": [{"@value": "foo"}] }]) }, - "datatype": { + datatype: { input: %({ "@context": {"@vocab": "http://example.com/"}, "http://example.org/verb": {"@value": "foo", "@type": "string"} @@ -971,7 +972,7 @@ "http://example.org/verb": [{"@value": "foo", "@type": "http://example.com/string"}] }]) }, - "expand-0028": { + 'expand-0028': { input: %({ "@context": { "@vocab": "http://example.org/vocab#", @@ -1010,17 +1011,17 @@ ]) } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://foo/bar/")} + it(title) { run_expand params.merge(base: "http://foo/bar/") } end end context "unmapped properties" do { - "unmapped key": { + 'unmapped key': { input: %({"foo": "bar"}), output: [] }, - "unmapped @type as datatype": { + 'unmapped @type as datatype': { input: %({ "http://example.com/foo": {"@value": "bar", "@type": "baz"} }), @@ -1028,11 +1029,11 @@ "http://example.com/foo": [{"@value": "bar", "@type": "http://example/baz"}] }]) }, - "unknown keyword": { + 'unknown keyword': { input: %({"@foo": "bar"}), output: [] }, - "value": { + value: { input: %({ "@context": {"ex": {"@id": "http://example.org/idrange", "@type": "@id"}}, "@id": "http://example.org/Subj", @@ -1040,7 +1041,7 @@ }), output: [] }, - "context reset": { + 'context reset': { input: %({ "@context": {"ex": "http://example.org/", "prop": "ex:prop"}, "@id": "http://example.org/id1", @@ -1058,13 +1059,13 @@ }]) } }.each do |title, params| - it(title) {run_expand params.merge(base: "http://example/")} + it(title) { run_expand params.merge(base: "http://example/") } end end context "@container: @index" do { - "string annotation": { + 'string annotation': { input: %({ "@context": { "container": { @@ -1086,14 +1087,14 @@ {"@value": "The Queen", "@index": "en"} ] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end context "@index: property" do { - "error if @version is json-ld-1.0": { + 'error if @version is json-ld-1.0': { input: %({ "@context": { "@vocab": "http://example.com/", @@ -1108,7 +1109,7 @@ exception: JSON::LD::JsonLdError::InvalidTermDefinition, processingMode: 'json-ld-1.0' }, - "error if @container does not include @index": { + 'error if @container does not include @index': { input: %({ "@context": { "@version": 1.1, @@ -1123,7 +1124,7 @@ }), exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "error if @index is a keyword": { + 'error if @index is a keyword': { input: %({ "@context": { "@version": 1.1, @@ -1142,7 +1143,7 @@ }), exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "error if @index is not a string": { + 'error if @index is not a string': { input: %({ "@context": { "@version": 1.1, @@ -1161,7 +1162,7 @@ }), exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "error if attempting to add property to value object": { + 'error if attempting to add property to value object': { input: %({ "@context": { "@version": 1.1, @@ -1180,7 +1181,7 @@ }), exception: JSON::LD::JsonLdError::InvalidValueObject }, - "property-valued index expands to property value, instead of @index (value)": { + 'property-valued index expands to property value, instead of @index (value)': { input: %({ "@context": { "@version": 1.1, @@ -1203,7 +1204,7 @@ ] }]) }, - "property-valued index appends to property value, instead of @index (value)": { + 'property-valued index appends to property value, instead of @index (value)': { input: %({ "@context": { "@version": 1.1, @@ -1229,7 +1230,7 @@ ] }]) }, - "property-valued index expands to property value, instead of @index (node)": { + 'property-valued index expands to property value, instead of @index (node)': { input: %({ "@context": { "@version": 1.1, @@ -1253,7 +1254,7 @@ ] }]) }, - "property-valued index appends to property value, instead of @index (node)": { + 'property-valued index appends to property value, instead of @index (node)': { input: %({ "@context": { "@version": 1.1, @@ -1280,7 +1281,7 @@ ] }]) }, - "property-valued index does not output property for @none": { + 'property-valued index does not output property for @none': { input: %({ "@context": { "@version": 1.1, @@ -1306,34 +1307,34 @@ {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}]} ] }]) - }, + } }.each do |title, params| - it(title) {run_expand(validate: true, **params)} + it(title) { run_expand(validate: true, **params) } end end end context "@container: @list" do { - "empty": { + empty: { input: %({"http://example.com/foo": {"@list": []}}), output: %([{"http://example.com/foo": [{"@list": []}]}]) }, - "coerced empty": { + 'coerced empty': { input: %({ "@context": {"http://example.com/foo": {"@container": "@list"}}, "http://example.com/foo": [] }), output: %([{"http://example.com/foo": [{"@list": []}]}]) }, - "coerced single element": { + 'coerced single element': { input: %({ "@context": {"http://example.com/foo": {"@container": "@list"}}, "http://example.com/foo": [ "foo" ] }), output: %([{"http://example.com/foo": [{"@list": [{"@value": "foo"}]}]}]) }, - "coerced multiple elements": { + 'coerced multiple elements': { input: %({ "@context": {"http://example.com/foo": {"@container": "@list"}}, "http://example.com/foo": [ "foo", "bar" ] @@ -1342,7 +1343,7 @@ "http://example.com/foo": [{"@list": [ {"@value": "foo"}, {"@value": "bar"} ]}] }]) }, - "native values in list": { + 'native values in list': { input: %({ "http://example.com/foo": {"@list": [1, 2]} }), @@ -1350,7 +1351,7 @@ "http://example.com/foo": [{"@list": [{"@value": 1}, {"@value": 2}]}] }]) }, - "explicit list with coerced @id values": { + 'explicit list with coerced @id values': { input: %({ "@context": {"http://example.com/foo": {"@type": "@id"}}, "http://example.com/foo": {"@list": ["http://foo", "http://bar"]} @@ -1359,7 +1360,7 @@ "http://example.com/foo": [{"@list": [{"@id": "http://foo"}, {"@id": "http://bar"}]}] }]) }, - "explicit list with coerced datatype values": { + 'explicit list with coerced datatype values': { input: %({ "@context": {"http://example.com/foo": {"@type": "http://www.w3.org/2001/XMLSchema#date"}}, "http://example.com/foo": {"@list": ["2012-04-12"]} @@ -1368,7 +1369,7 @@ "http://example.com/foo": [{"@list": [{"@value": "2012-04-12", "@type": "http://www.w3.org/2001/XMLSchema#date"}]}] }]) }, - "expand-0004": { + 'expand-0004': { input: %({ "@context": { "mylist1": {"@id": "http://example.com/mylist1", "@container": "@list"}, @@ -1392,7 +1393,7 @@ } ]) }, - "@list containing @list": { + '@list containing @list': { input: %({ "http://example.com/foo": {"@list": [{"@list": ["baz"]}]} }), @@ -1400,7 +1401,7 @@ "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}] }]) }, - "@list containing empty @list": { + '@list containing empty @list': { input: %({ "http://example.com/foo": {"@list": [{"@list": []}]} }), @@ -1408,7 +1409,7 @@ "http://example.com/foo": [{"@list": [{"@list": []}]}] }]) }, - "@list containing @list (with coercion)": { + '@list containing @list (with coercion)': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [{"@list": ["baz"]}] @@ -1417,7 +1418,7 @@ "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}] }]) }, - "@list containing empty @list (with coercion)": { + '@list containing empty @list (with coercion)': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [{"@list": []}] @@ -1426,7 +1427,7 @@ "http://example.com/foo": [{"@list": [{"@list": []}]}] }]) }, - "coerced @list containing an array": { + 'coerced @list containing an array': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["baz"]] @@ -1435,7 +1436,7 @@ "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}] }]) }, - "coerced @list containing an empty array": { + 'coerced @list containing an empty array': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [[]] @@ -1444,7 +1445,7 @@ "http://example.com/foo": [{"@list": [{"@list": []}]}] }]) }, - "coerced @list containing deep arrays": { + 'coerced @list containing deep arrays': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [[["baz"]]] @@ -1453,16 +1454,16 @@ "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}] }]) }, - "coerced @list containing deep empty arrays": { + 'coerced @list containing deep empty arrays': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [[[]]] }), output: %([{ "http://example.com/foo": [{"@list": [{"@list": [{"@list": []}]}]}] - }]), + }]) }, - "coerced @list containing multiple lists": { + 'coerced @list containing multiple lists': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["a"], ["b"]] @@ -1474,7 +1475,7 @@ ]}] }]) }, - "coerced @list containing mixed list values": { + 'coerced @list containing mixed list values': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [["a"], "b"] @@ -1485,19 +1486,19 @@ {"@value": "b"} ]}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "@container: @set" do { - "empty": { + empty: { input: %({"http://example.com/foo": {"@set": []}}), output: %([{"http://example.com/foo": []}]) }, - "coerced empty": { + 'coerced empty': { input: %({ "@context": {"http://example.com/foo": {"@container": "@set"}}, "http://example.com/foo": [] @@ -1506,7 +1507,7 @@ "http://example.com/foo": [] }]) }, - "coerced single element": { + 'coerced single element': { input: %({ "@context": {"http://example.com/foo": {"@container": "@set"}}, "http://example.com/foo": [ "foo" ] @@ -1515,7 +1516,7 @@ "http://example.com/foo": [ {"@value": "foo"} ] }]) }, - "coerced multiple elements": { + 'coerced multiple elements': { input: %({ "@context": {"http://example.com/foo": {"@container": "@set"}}, "http://example.com/foo": [ "foo", "bar" ] @@ -1524,7 +1525,7 @@ "http://example.com/foo": [ {"@value": "foo"}, {"@value": "bar"} ] }]) }, - "array containing set": { + 'array containing set': { input: %({ "http://example.com/foo": [{"@set": []}] }), @@ -1532,7 +1533,7 @@ "http://example.com/foo": [] }]) }, - "Free-floating values in sets": { + 'Free-floating values in sets': { input: %({ "@context": {"property": "http://example.com/property"}, "@graph": [{ @@ -1556,13 +1557,13 @@ }]) } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "@container: @language" do { - "simple map": { + 'simple map': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1588,7 +1589,7 @@ } ]) }, - "simple map with @none": { + 'simple map with @none': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1616,7 +1617,7 @@ } ]) }, - "simple map with alias of @none": { + 'simple map with alias of @none': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1645,7 +1646,7 @@ } ]) }, - "simple map with default direction": { + 'simple map with default direction': { input: %({ "@context": { "@direction": "ltr", @@ -1672,7 +1673,7 @@ } ]) }, - "simple map with term direction": { + 'simple map with term direction': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1699,7 +1700,7 @@ } ]) }, - "simple map with overriding term direction": { + 'simple map with overriding term direction': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1727,7 +1728,7 @@ } ]) }, - "simple map with overriding null direction": { + 'simple map with overriding null direction': { input: %({ "@context": { "vocab": "http://example.com/vocab/", @@ -1755,7 +1756,7 @@ } ]) }, - "expand-0035": { + 'expand-0035': { input: %({ "@context": { "@vocab": "http://example.com/vocab/", @@ -1788,13 +1789,13 @@ ]) } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "@container: @id" do { - "Adds @id to object not having an @id": { + 'Adds @id to object not having an @id': { input: %({ "@context": { "@vocab": "http://example/", @@ -1812,7 +1813,7 @@ ] }]) }, - "Retains @id in object already having an @id": { + 'Retains @id in object already having an @id': { input: %({ "@context": { "@vocab": "http://example/", @@ -1830,7 +1831,7 @@ ] }]) }, - "Adds expanded @id to object": { + 'Adds expanded @id to object': { input: %({ "@context": { "@vocab": "http://example/", @@ -1847,7 +1848,7 @@ }]), base: "http://example.org/" }, - "Raises InvalidContainerMapping if processingMode is 1.0": { + 'Raises InvalidContainerMapping if processingMode is 1.0': { input: %({ "@context": { "@vocab": "http://example/", @@ -1861,7 +1862,7 @@ processingMode: 'json-ld-1.0', exception: JSON::LD::JsonLdError::InvalidContainerMapping }, - "Does not add @id if it is @none, or expands to @none": { + 'Does not add @id if it is @none, or expands to @none': { input: %({ "@context": { "@vocab": "http://example/", @@ -1881,13 +1882,13 @@ }]) } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end context "@container: @type" do { - "Adds @type to object not having an @type": { + 'Adds @type to object not having an @type': { input: %({ "@context": { "@vocab": "http://example/", @@ -1905,7 +1906,7 @@ ] }]) }, - "Prepends @type in object already having an @type": { + 'Prepends @type in object already having an @type': { input: %({ "@context": { "@vocab": "http://example/", @@ -1929,7 +1930,7 @@ ] }]) }, - "Adds vocabulary expanded @type to object": { + 'Adds vocabulary expanded @type to object': { input: %({ "@context": { "@vocab": "http://example/", @@ -1945,7 +1946,7 @@ ] }]) }, - "Adds document expanded @type to object": { + 'Adds document expanded @type to object': { input: %({ "@context": { "@vocab": "http://example/", @@ -1962,7 +1963,7 @@ ] }]) }, - "Does not add @type if it is @none, or expands to @none": { + 'Does not add @type if it is @none, or expands to @none': { input: %({ "@context": { "@vocab": "http://example/", @@ -1981,7 +1982,7 @@ ] }]) }, - "Raises InvalidContainerMapping if processingMode is 1.0": { + 'Raises InvalidContainerMapping if processingMode is 1.0': { input: %({ "@context": { "@vocab": "http://example/", @@ -1994,15 +1995,15 @@ }), processingMode: 'json-ld-1.0', exception: JSON::LD::JsonLdError::InvalidContainerMapping - }, + } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end context "@container: @graph" do { - "Creates a graph object given a value": { + 'Creates a graph object given a value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2020,7 +2021,7 @@ }] }]) }, - "Creates a graph object within an array given a value": { + 'Creates a graph object within an array given a value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2038,7 +2039,7 @@ }] }]) }, - "Creates an graph object if value is a graph": { + 'Creates an graph object if value is a graph': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2059,14 +2060,14 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end context "+ @index" do { - "Creates a graph object given an indexed value": { + 'Creates a graph object given an indexed value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2085,7 +2086,7 @@ }] }]) }, - "Creates a graph object given an indexed value with index @none": { + 'Creates a graph object given an indexed value with index @none': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2103,7 +2104,7 @@ }] }]) }, - "Creates a graph object given an indexed value with index alias of @none": { + 'Creates a graph object given an indexed value with index alias of @none': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2122,7 +2123,7 @@ }] }]) }, - "Creates a graph object given an indexed value with @set": { + 'Creates a graph object given an indexed value with @set': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2141,7 +2142,7 @@ }] }]) }, - "Does not create a new graph object if indexed value is already a graph object": { + 'Does not create a new graph object if indexed value is already a graph object': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2163,14 +2164,14 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end context "@index: property" do { - "it expands to property value, instead of @index": { + 'it expands to property value, instead of @index': { input: %({ "@context": { "@version": 1.1, @@ -2189,16 +2190,16 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_expand(validate: true, **params)} + it(title) { run_expand(validate: true, **params) } end end end context "+ @id" do { - "Creates a graph object given an indexed value": { + 'Creates a graph object given an indexed value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2217,7 +2218,7 @@ }] }]) }, - "Creates a graph object given an indexed value of @none": { + 'Creates a graph object given an indexed value of @none': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2235,7 +2236,7 @@ }] }]) }, - "Creates a graph object given an indexed value of alias of @none": { + 'Creates a graph object given an indexed value of alias of @none': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2254,7 +2255,7 @@ }] }]) }, - "Creates a graph object given an indexed value with @set": { + 'Creates a graph object given an indexed value with @set': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2273,7 +2274,7 @@ }] }]) }, - "Does not create a new graph object if indexed value is already a graph object": { + 'Does not create a new graph object if indexed value is already a graph object': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2295,16 +2296,16 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end end context "@included" do { - "Basic Included array": { + 'Basic Included array': { input: %({ "@context": { "@version": 1.1, @@ -2322,7 +2323,7 @@ }] }]) }, - "Basic Included object": { + 'Basic Included object': { input: %({ "@context": { "@version": 1.1, @@ -2340,7 +2341,7 @@ }] }]) }, - "Multiple properties mapping to @included are folded together": { + 'Multiple properties mapping to @included are folded together': { input: %({ "@context": { "@version": 1.1, @@ -2358,7 +2359,7 @@ ] }]) }, - "Included containing @included": { + 'Included containing @included': { input: %({ "@context": { "@version": 1.1, @@ -2382,7 +2383,7 @@ }] }]) }, - "Property value with @included": { + 'Property value with @included': { input: %({ "@context": { "@version": 1.1, @@ -2404,7 +2405,7 @@ }] }]) }, - "json.api example": { + 'json.api example': { input: %({ "@context": { "@version": 1.1, @@ -2538,7 +2539,7 @@ }] }]) }, - "Error if @included value is a string": { + 'Error if @included value is a string': { input: %({ "@context": { "@version": 1.1, @@ -2548,7 +2549,7 @@ }), exception: JSON::LD::JsonLdError::InvalidIncludedValue }, - "Error if @included value is a value object": { + 'Error if @included value is a value object': { input: %({ "@context": { "@version": 1.1, @@ -2558,7 +2559,7 @@ }), exception: JSON::LD::JsonLdError::InvalidIncludedValue }, - "Error if @included value is a list object": { + 'Error if @included value is a list object': { input: %({ "@context": { "@version": 1.1, @@ -2567,15 +2568,15 @@ "@included": {"@list": ["value"]} }), exception: JSON::LD::JsonLdError::InvalidIncludedValue - }, + } }.each do |title, params| - it(title) {run_expand(params)} + it(title) { run_expand(params) } end end context "@nest" do { - "Expands input using @nest": { + 'Expands input using @nest': { input: %({ "@context": {"@vocab": "http://example.org/"}, "p1": "v1", @@ -2588,7 +2589,7 @@ "http://example.org/p2": [{"@value": "v2"}] }]) }, - "Expands input using aliased @nest": { + 'Expands input using aliased @nest': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2604,7 +2605,7 @@ "http://example.org/p2": [{"@value": "v2"}] }]) }, - "Appends nested values when property at base and nested": { + 'Appends nested values when property at base and nested': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2624,7 +2625,7 @@ ] }]) }, - "Appends nested values from all @nest aliases in term order": { + 'Appends nested values from all @nest aliases in term order': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2649,7 +2650,7 @@ ] }]) }, - "Nested nested containers": { + 'Nested nested containers': { input: %({ "@context": { "@vocab": "http://example.org/" @@ -2672,7 +2673,7 @@ ] }]) }, - "Arrays of nested values": { + 'Arrays of nested values': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2694,7 +2695,7 @@ ] }]) }, - "A nest of arrays": { + 'A nest of arrays': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2718,35 +2719,35 @@ ] }]) }, - "@nest MUST NOT have a string value": { + '@nest MUST NOT have a string value': { input: %({ "@context": {"@vocab": "http://example.org/"}, "@nest": "This should generate an error" }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest MUST NOT have a boolen value": { + '@nest MUST NOT have a boolen value': { input: %({ "@context": {"@vocab": "http://example.org/"}, "@nest": true }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest MUST NOT have a numeric value": { + '@nest MUST NOT have a numeric value': { input: %({ "@context": {"@vocab": "http://example.org/"}, "@nest": 1 }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest MUST NOT have a value object value": { + '@nest MUST NOT have a value object value': { input: %({ "@context": {"@vocab": "http://example.org/"}, "@nest": {"@value": "This should generate an error"} }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest in term definition MUST NOT be a non-@nest keyword": { + '@nest in term definition MUST NOT be a non-@nest keyword': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2756,7 +2757,7 @@ }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest in term definition MUST NOT have a boolen value": { + '@nest in term definition MUST NOT have a boolen value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2766,7 +2767,7 @@ }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "@nest in term definition MUST NOT have a numeric value": { + '@nest in term definition MUST NOT have a numeric value': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2776,7 +2777,7 @@ }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "Nested @container: @list": { + 'Nested @container: @list': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2794,7 +2795,7 @@ ]}] }]) }, - "Nested @container: @index": { + 'Nested @container: @index': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2815,7 +2816,7 @@ ] }]) }, - "Nested @container: @language": { + 'Nested @container: @language': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2836,7 +2837,7 @@ ] }]) }, - "Nested @container: @type": { + 'Nested @container: @type': { input: %({ "@context": { "@vocab": "http://example/", @@ -2857,7 +2858,7 @@ ] }]) }, - "Nested @container: @id": { + 'Nested @container: @id': { input: %({ "@context": { "@vocab": "http://example/", @@ -2878,7 +2879,7 @@ ] }]) }, - "Nest term an invalid keyword": { + 'Nest term an invalid keyword': { input: %({ "@context": { "term": {"@id": "http://example/term", "@nest": "@id"} @@ -2886,7 +2887,7 @@ }), exception: JSON::LD::JsonLdError::InvalidNestValue }, - "Nest in @reverse": { + 'Nest in @reverse': { input: %({ "@context": { "term": {"@reverse": "http://example/term", "@nest": "@nest"} @@ -2894,7 +2895,7 @@ }), exception: JSON::LD::JsonLdError::InvalidReverseProperty }, - "Raises InvalidTermDefinition if processingMode is 1.0": { + 'Raises InvalidTermDefinition if processingMode is 1.0': { input: %({ "@context": { "@vocab": "http://example.org/", @@ -2909,7 +2910,7 @@ validate: true, exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "Applies property scoped contexts which are aliases of @nest": { + 'Applies property scoped contexts which are aliases of @nest': { input: %({ "@context": { "@version": 1.1, @@ -2930,13 +2931,13 @@ }]) } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end context "scoped context" do { - "adding new term": { + 'adding new term': { input: %({ "@context": { "@vocab": "http://example/", @@ -2952,7 +2953,7 @@ } ]) }, - "overriding a term": { + 'overriding a term': { input: %({ "@context": { "@vocab": "http://example/", @@ -2969,7 +2970,7 @@ } ]) }, - "property and value with different terms mapping to the same expanded property": { + 'property and value with different terms mapping to the same expanded property': { input: %({ "@context": { "@vocab": "http://example/", @@ -2989,7 +2990,7 @@ } ]) }, - "deep @context affects nested nodes": { + 'deep @context affects nested nodes': { input: %({ "@context": { "@vocab": "http://example/", @@ -3011,7 +3012,7 @@ } ]) }, - "scoped context layers on intemediate contexts": { + 'scoped context layers on intemediate contexts': { input: %({ "@context": { "@vocab": "http://example/", @@ -3038,7 +3039,7 @@ "http://example/c": [{"@value": "C in example"}] }]) }, - "Raises InvalidTermDefinition if processingMode is 1.0": { + 'Raises InvalidTermDefinition if processingMode is 1.0': { input: %({ "@context": { "@vocab": "http://example/", @@ -3052,7 +3053,7 @@ validate: true, exception: JSON::LD::JsonLdError::InvalidTermDefinition }, - "Scoped on id map": { + 'Scoped on id map': { input: %({ "@context": { "@version": 1.1, @@ -3102,13 +3103,13 @@ }]) } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end context "scoped context on @type" do { - "adding new term": { + 'adding new term': { input: %({ "@context": { "@vocab": "http://example/", @@ -3125,7 +3126,7 @@ } ]) }, - "overriding a term": { + 'overriding a term': { input: %({ "@context": { "@vocab": "http://example/", @@ -3143,7 +3144,7 @@ } ]) }, - "alias of @type": { + 'alias of @type': { input: %({ "@context": { "@vocab": "http://example/", @@ -3161,7 +3162,7 @@ } ]) }, - "deep @context does not affect nested nodes": { + 'deep @context does not affect nested nodes': { input: %({ "@context": { "@vocab": "http://example/", @@ -3179,7 +3180,7 @@ } ]) }, - "scoped context layers on intemediate contexts": { + 'scoped context layers on intemediate contexts': { input: %({ "@context": { "@vocab": "http://example/", @@ -3202,7 +3203,7 @@ "http://example/c": [{"@value": "C in example"}] }]) }, - "with @container: @type": { + 'with @container: @type': { input: %({ "@context": { "@vocab": "http://example/", @@ -3219,7 +3220,7 @@ ] }]) }, - "orders lexicographically": { + 'orders lexicographically': { input: %({ "@context": { "@vocab": "http://example/", @@ -3236,7 +3237,7 @@ ] }]) }, - "Raises InvalidTermDefinition if processingMode is 1.0": { + 'Raises InvalidTermDefinition if processingMode is 1.0': { input: %({ "@context": { "@vocab": "http://example/", @@ -3247,15 +3248,15 @@ processingMode: 'json-ld-1.0', validate: true, exception: JSON::LD::JsonLdError::InvalidTermDefinition - }, + } }.each do |title, params| - it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))} + it(title) { run_expand({ processingMode: "json-ld-1.1" }.merge(params)) } end end context "@reverse" do { - "@container: @reverse": { + '@container: @reverse': { input: %({ "@context": { "@vocab": "http://example/", @@ -3275,7 +3276,7 @@ } }]) }, - "expand-0037": { + 'expand-0037': { input: %({ "@context": { "name": "http://xmlns.com/foaf/0.1/name" @@ -3312,7 +3313,7 @@ } ]) }, - "expand-0043": { + 'expand-0043': { input: %({ "@context": { "name": "http://xmlns.com/foaf/0.1/name", @@ -3362,16 +3363,16 @@ } ]) }, - "@reverse object with an @id property": { + '@reverse object with an @id property': { input: %({ "@id": "http://example/foo", "@reverse": { "@id": "http://example/bar" } }), - exception: JSON::LD::JsonLdError::InvalidReversePropertyMap, + exception: JSON::LD::JsonLdError::InvalidReversePropertyMap }, - "Explicit and implicit @reverse in same object": { + 'Explicit and implicit @reverse in same object': { input: %({ "@context": { "fooOf": {"@reverse": "ex:foo", "@type": "@id"} @@ -3390,7 +3391,7 @@ } }]) }, - "Two properties both with @reverse": { + 'Two properties both with @reverse': { input: %({ "@context": { "fooOf": {"@reverse": "ex:foo", "@type": "@id"}, @@ -3407,15 +3408,15 @@ "ex:foo": [{"@id": "ex:o1"}] } }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "JSON-LD-star" do { - "node with embedded subject without rdfstar option": { + 'node with embedded subject without rdfstar option': { input: %({ "@id": { "@id": "ex:rei", @@ -3425,7 +3426,7 @@ }), exception: JSON::LD::JsonLdError::InvalidIdValue }, - "node object with @annotation property is ignored without rdfstar option": { + 'node object with @annotation property is ignored without rdfstar option': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -3440,7 +3441,7 @@ "ex:knows": [{"@id": "ex:fred"}] }]) }, - "value object with @annotation property is ignored without rdfstar option": { + 'value object with @annotation property is ignored without rdfstar option': { input: %({ "@id": "ex:bob", "ex:age": { @@ -3454,13 +3455,13 @@ "@id": "ex:bob", "ex:age": [{"@value": 23}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end { - "node with embedded subject having no @id": { + 'node with embedded subject having no @id': { input: %({ "@id": { "ex:prop": "value" @@ -3474,7 +3475,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having IRI @id": { + 'node with embedded subject having IRI @id': { input: %({ "@id": { "@id": "ex:rei", @@ -3490,7 +3491,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having BNode @id": { + 'node with embedded subject having BNode @id': { input: %({ "@id": { "@id": "_:rei", @@ -3506,7 +3507,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having a type": { + 'node with embedded subject having a type': { input: %({ "@id": { "@id": "ex:rei", @@ -3522,7 +3523,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having an IRI value": { + 'node with embedded subject having an IRI value': { input: %({ "@id": { "@id": "ex:rei", @@ -3538,7 +3539,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having an BNode value": { + 'node with embedded subject having an BNode value': { input: %({ "@id": { "@id": "ex:rei", @@ -3554,7 +3555,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with recursive embedded subject": { + 'node with recursive embedded subject': { input: %({ "@id": { "@id": { @@ -3576,7 +3577,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "illegal node with subject having no property": { + 'illegal node with subject having no property': { input: %({ "@id": { "@id": "ex:rei" @@ -3585,7 +3586,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having multiple properties": { + 'illegal node with subject having multiple properties': { input: %({ "@id": { "@id": "ex:rei", @@ -3595,7 +3596,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having multiple types": { + 'illegal node with subject having multiple types': { input: %({ "@id": { "@id": "ex:rei", @@ -3605,7 +3606,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having type and property": { + 'illegal node with subject having type and property': { input: %({ "@id": { "@id": "ex:rei", @@ -3616,7 +3617,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "node with embedded object": { + 'node with embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -3636,7 +3637,7 @@ }] }]) }, - "node with embedded object having properties": { + 'node with embedded object having properties': { input: %({ "@id": "ex:subj", "ex:value": { @@ -3658,7 +3659,7 @@ }] }]) }, - "node with recursive embedded object": { + 'node with recursive embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -3686,7 +3687,7 @@ }] }]) }, - "node with @annotation property on value object": { + 'node with @annotation property on value object': { input: %({ "@id": "ex:bob", "ex:age": { @@ -3702,7 +3703,7 @@ }] }]) }, - "node with @annotation property on node object": { + 'node with @annotation property on node object': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -3722,7 +3723,7 @@ }] }]) }, - "node with @annotation property multiple values": { + 'node with @annotation property multiple values': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -3750,7 +3751,7 @@ }] }]) }, - "node with @annotation property that is on the top-level is invalid": { + 'node with @annotation property that is on the top-level is invalid': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -3758,7 +3759,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation property on a top-level graph node is invalid": { + 'node with @annotation property on a top-level graph node is invalid': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -3770,7 +3771,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation property having @id is invalid": { + 'node with @annotation property having @id is invalid': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -3783,7 +3784,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation property with value object value is invalid": { + 'node with @annotation property with value object value is invalid': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -3793,7 +3794,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation on a list": { + 'node with @annotation on a list': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -3803,7 +3804,7 @@ }), exception: JSON::LD::JsonLdError::InvalidSetOrListObject }, - "node with @annotation on a list value": { + 'node with @annotation on a list value': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -3817,7 +3818,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation property on a top-level @included node is invalid": { + 'node with @annotation property on a top-level @included node is invalid': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -3829,7 +3830,7 @@ }), exception: JSON::LD::JsonLdError::InvalidAnnotation }, - "node with @annotation property on embedded subject": { + 'node with @annotation property on embedded subject': { input: %({ "@id": { "@id": "ex:rei", @@ -3853,7 +3854,7 @@ }] }]) }, - "node with @annotation property on embedded object": { + 'node with @annotation property on embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -3877,7 +3878,7 @@ }] }]) }, - "embedded node with reverse relationship": { + 'embedded node with reverse relationship': { input: %({ "@context": { "rel": {"@reverse": "ex:rel"} @@ -3890,7 +3891,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "embedded node with expanded reverse relationship": { + 'embedded node with expanded reverse relationship': { input: %({ "@id": { "@id": "ex:rei", @@ -3902,7 +3903,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "embedded node used as subject in reverse relationship": { + 'embedded node used as subject in reverse relationship': { input: %({ "@context": { "rel": {"@reverse": "ex:rel"} @@ -3923,7 +3924,7 @@ } }]) }, - "embedded node used as object in reverse relationship": { + 'embedded node used as object in reverse relationship': { input: %({ "@context": { "rel": {"@reverse": "ex:rel"} @@ -3950,7 +3951,7 @@ } }]) }, - "node with @annotation property on node object with reverse relationship": { + 'node with @annotation property on node object with reverse relationship': { input: %({ "@context": { "knownBy": {"@reverse": "ex:knows"} @@ -3975,7 +3976,7 @@ } }]) }, - "reverse relationship inside annotation": { + 'reverse relationship inside annotation': { input: %({ "@context": { "claims": {"@reverse": "ex:claims", "@type": "@id"} @@ -4001,9 +4002,9 @@ }] }] }]) - }, + } }.each do |title, params| - it(title) {run_expand params.merge(rdfstar: true)} + it(title) { run_expand params.merge(rdfstar: true) } end end @@ -4014,13 +4015,14 @@ require 'rexml/document' context "html" do - %w(Nokogiri REXML).each do |impl| + %w[Nokogiri REXML].each do |impl| next unless Module.constants.map(&:to_s).include?(impl) + context impl do - let(:library) {impl.downcase.to_s.to_sym} + let(:library) { impl.downcase.to_s.to_sym } { - "Expands embedded JSON-LD script element": { + 'Expands embedded JSON-LD script element': { input: %( @@ -4038,7 +4040,7 @@ "http://example.com/foo": [{"@list": [{"@value": "bar"}]}] }]) }, - "Expands first script element": { + 'Expands first script element': { input: %( @@ -4065,7 +4067,7 @@ "http://example.com/foo": [{"@list": [{"@value": "bar"}]}] }]) }, - "Expands targeted script element": { + 'Expands targeted script element': { input: %( @@ -4094,7 +4096,7 @@ ]), base: "http://example.org/doc#second" }, - "Expands all script elements with extractAllScripts option": { + 'Expands all script elements with extractAllScripts option': { input: %( @@ -4129,7 +4131,7 @@ ]), extractAllScripts: true }, - "Expands multiple scripts where one is an array": { + 'Expands multiple scripts where one is an array': { input: %( @@ -4156,16 +4158,16 @@ ]), extractAllScripts: true }, - "Errors no script element": { + 'Errors no script element': { input: %(), exception: JSON::LD::JsonLdError::LoadingDocumentFailed }, - "Expands as empty with no script element and extractAllScripts": { + 'Expands as empty with no script element and extractAllScripts': { input: %(), output: %([]), extractAllScripts: true }, - "Expands script element with HTML character references": { + 'Expands script element with HTML character references': { input: %( @@ -4181,7 +4183,7 @@ "http://example/foo": [{"@value": "<&>"}] }]) }, - "Expands embedded JSON-LD script element relative to document base": { + 'Expands embedded JSON-LD script element relative to document base': { input: %( @@ -4202,7 +4204,7 @@ }]), base: "http://example.org/doc" }, - "Expands embedded JSON-LD script element relative to HTML base": { + 'Expands embedded JSON-LD script element relative to HTML base': { input: %( @@ -4224,7 +4226,7 @@ }]), base: "http://example.org/doc" }, - "Expands embedded JSON-LD script element relative to relative HTML base": { + 'Expands embedded JSON-LD script element relative to relative HTML base': { input: %( @@ -4246,7 +4248,7 @@ }]), base: "http://example.org/doc" }, - "Errors if no element found at target": { + 'Errors if no element found at target': { input: %( @@ -4272,7 +4274,7 @@ base: "http://example.org/doc#third", exception: JSON::LD::JsonLdError::LoadingDocumentFailed }, - "Errors if targeted element is not a script element": { + 'Errors if targeted element is not a script element': { input: %( @@ -4289,7 +4291,7 @@ base: "http://example.org/doc#first", exception: JSON::LD::JsonLdError::LoadingDocumentFailed }, - "Errors if targeted element does not have type application/ld+json": { + 'Errors if targeted element does not have type application/ld+json': { input: %( @@ -4306,7 +4308,7 @@ base: "http://example.org/doc#first", exception: JSON::LD::JsonLdError::LoadingDocumentFailed }, - "Errors if uncommented script text contains comment": { + 'Errors if uncommented script text contains comment': { input: %( @@ -4325,7 +4327,7 @@ exception: JSON::LD::JsonLdError::InvalidScriptElement, not: :rexml }, - "Errors if end comment missing": { + 'Errors if end comment missing': { input: %( @@ -4343,7 +4345,7 @@ exception: JSON::LD::JsonLdError::InvalidScriptElement, not: :rexml }, - "Errors if start comment missing": { + 'Errors if start comment missing': { input: %( @@ -4360,7 +4362,7 @@ ), exception: JSON::LD::JsonLdError::InvalidScriptElement }, - "Errors if uncommented script is not valid JSON": { + 'Errors if uncommented script is not valid JSON': { input: %( @@ -4370,12 +4372,12 @@ ), exception: JSON::LD::JsonLdError::InvalidScriptElement - }, + } }.each do |title, params| it(title) do skip "rexml" if params[:not] == library params = params.merge(input: StringIO.new(params[:input])) - params[:input].send(:define_singleton_method, :content_type) {"text/html"} + params[:input].send(:define_singleton_method, :content_type) { "text/html" } run_expand params.merge(validate: true, library: library) end end @@ -4385,7 +4387,7 @@ context "deprectaions" do { - "blank node property": { + 'blank node property': { input: %({"_:bn": "value"}), output: %([{"_:bn": [{"@value": "value"}]}]) } @@ -4402,22 +4404,22 @@ context "exceptions" do { - "non-null @value and null @type": { + 'non-null @value and null @type': { input: %({"http://example.com/foo": {"@value": "foo", "@type": null}}), exception: JSON::LD::JsonLdError::InvalidTypeValue }, - "non-null @value and null @language": { + 'non-null @value and null @language': { input: %({"http://example.com/foo": {"@value": "foo", "@language": null}}), exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString }, - "value with null language": { + 'value with null language': { input: %({ "@context": {"@language": "en"}, "http://example.org/nolang": {"@value": "no language", "@language": null} }), exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString }, - "colliding keywords": { + 'colliding keywords': { input: %({ "@context": { "id": "@id", @@ -4426,9 +4428,9 @@ "id": "http://example/foo", "ID": "http://example/bar" }), - exception: JSON::LD::JsonLdError::CollidingKeywords, + exception: JSON::LD::JsonLdError::CollidingKeywords }, - "@language and @type": { + '@language and @type': { input: %({ "ex:p": { "@value": "v", @@ -4439,7 +4441,7 @@ exception: JSON::LD::JsonLdError::InvalidValueObject, processingMode: 'json-ld-1.1' }, - "@direction and @type": { + '@direction and @type': { input: %({ "ex:p": { "@value": "v", @@ -4449,15 +4451,15 @@ }), exception: JSON::LD::JsonLdError::InvalidValueObject, processingMode: 'json-ld-1.1' - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end context "problem cases" do { - "toRdf/0118": { + 'toRdf/0118': { input: %({ "@context": {"term": "_:term", "termId": { "@id": "term", "@type": "@id" }}, "termId": "term:AppendedToBlankNode" @@ -4465,27 +4467,28 @@ output: %([{ "_:term": [{"@id": "_:termAppendedToBlankNode"}] }]) - }, + } }.each do |title, params| - it(title) {run_expand params} + it(title) { run_expand params } end end end def run_expand(params) - input, output = params[:input], params[:output] + input = params[:input] + output = params[:output] params[:base] ||= nil - input = ::JSON.parse(input) if input.is_a?(String) - output = ::JSON.parse(output) if output.is_a?(String) + input = JSON.parse(input) if input.is_a?(String) + output = JSON.parse(output) if output.is_a?(String) pending params.fetch(:pending, "test implementation") unless input if params[:exception] - expect {JSON::LD::API.expand(input, **params)}.to raise_error(params[:exception]) + expect { JSON::LD::API.expand(input, **params) }.to raise_error(params[:exception]) else jld = nil if params[:write] - expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.to write(params[:write]).to(:error) + expect { jld = JSON::LD::API.expand(input, logger: logger, **params) }.to write(params[:write]).to(:error) else - expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.not_to write.to(:error) + expect { jld = JSON::LD::API.expand(input, logger: logger, **params) }.not_to write.to(:error) end expect(jld).to produce_jsonld(output, logger) diff --git a/spec/flatten_spec.rb b/spec/flatten_spec.rb index 1115e735..a8fefe3b 100644 --- a/spec/flatten_spec.rb +++ b/spec/flatten_spec.rb @@ -1,18 +1,19 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } describe ".flatten" do { - "single object": { + 'single object': { input: %({"@id": "http://example.com", "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"}), output: %([ {"@id": "http://example.com", "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"]} ]) }, - "embedded object": { + 'embedded object': { input: %({ "@context": { "foaf": "http://xmlns.com/foaf/0.1/" @@ -36,7 +37,7 @@ } ]) }, - "embedded anon": { + 'embedded anon': { input: %({ "@context": { "foaf": "http://xmlns.com/foaf/0.1/" @@ -59,7 +60,7 @@ } ]) }, - "reverse properties": { + 'reverse properties': { input: %([ { "@id": "http://example.com/people/markus", @@ -103,8 +104,8 @@ } ]) }, - "Simple named graph (Wikidata)": { - input: %q({ + 'Simple named graph (Wikidata)': { + input: '{ "@context": { "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "ex": "http://example.org/", @@ -133,8 +134,8 @@ "ex:hasReference": "http://www.wikipedia.org/" } ] - }), - output: %q([{ + }', + output: '[{ "@id": "http://example.org/ParisFact1", "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"], "http://example.org/hasReference": [ @@ -154,10 +155,10 @@ "@id": "http://example.org/location/Paris#this", "http://example.org/hasPopulation": [{"@value": 7000000}] }] - }]), + }]' }, - "Test Manifest (shortened)": { - input: %q{ + 'Test Manifest (shortened)': { + input: ' { "@id": "", "http://example/sequence": {"@list": [ @@ -168,8 +169,8 @@ } ]} } - }, - output: %q{ + ', + output: ' [{ "@id": "", "http://example/sequence": [{"@list": [{"@id": "#t0001"}]}] @@ -178,10 +179,10 @@ "http://example/input": [{"@id": "error-expand-0001-in.jsonld"}], "http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}] }] - }, + ' }, - "@reverse bnode issue (0045)": { - input: %q{ + '@reverse bnode issue (0045)': { + input: ' { "@context": { "foo": "http://example.org/foo", @@ -190,8 +191,8 @@ "foo": "Foo", "bar": [ "http://example.org/origin", "_:b0" ] } - }, - output: %q{ + ', + output: ' [ { "@id": "_:b0", @@ -206,10 +207,10 @@ "http://example.org/bar": [ { "@id": "_:b0" } ] } ] - }, + ', remap_nodes: true }, - "@list with embedded object": { + '@list with embedded object': { input: %([{ "http://example.com/foo": [{ "@list": [{ @@ -235,16 +236,16 @@ } ]) }, - "coerced @list containing an deep list": { + 'coerced @list containing an deep list': { input: %([{ "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}] }]), output: %([{ "@id": "_:b0", "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}] - }]), + }]) }, - "@list containing empty @list": { + '@list containing empty @list': { input: %({ "http://example.com/foo": {"@list": [{"@list": []}]} }), @@ -253,7 +254,7 @@ "http://example.com/foo": [{"@list": [{"@list": []}]}] }]) }, - "coerced @list containing mixed list values": { + 'coerced @list containing mixed list values': { input: %({ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}}, "foo": [ @@ -279,14 +280,14 @@ "http://example/Baz" ] }]) - }, + } }.each do |title, params| - it(title) {run_flatten(params)} + it(title) { run_flatten(params) } end context "@included" do { - "Basic Included array": { + 'Basic Included array': { input: %({ "@context": { "@version": 1.1, @@ -305,7 +306,7 @@ "http://example.org/prop": [{"@value": "value2"}] }]) }, - "Basic Included object": { + 'Basic Included object': { input: %({ "@context": { "@version": 1.1, @@ -324,7 +325,7 @@ "http://example.org/prop": [{"@value": "value2"}] }]) }, - "Multiple properties mapping to @included are folded together": { + 'Multiple properties mapping to @included are folded together': { input: %({ "@context": { "@version": 1.1, @@ -343,7 +344,7 @@ "http://example.org/prop": [{"@value": "value2"}] }]) }, - "Included containing @included": { + 'Included containing @included': { input: %({ "@context": { "@version": 1.1, @@ -368,7 +369,7 @@ "http://example.org/prop": [{"@value": "value3"}] }]) }, - "Property value with @included": { + 'Property value with @included': { input: %({ "@context": { "@version": 1.1, @@ -394,7 +395,7 @@ "@type": ["http://example.org/Bar"] }]) }, - "json.api example": { + 'json.api example': { input: %({ "@context": { "@version": 1.1, @@ -525,16 +526,16 @@ ], "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/author"}] }]) - }, + } }.each do |title, params| - it(title) {run_flatten(params)} + it(title) { run_flatten(params) } end end end context "html" do { - "Flattens embedded JSON-LD script element": { + 'Flattens embedded JSON-LD script element': { input: %( @@ -556,7 +557,7 @@ "@graph": [{"@id": "_:b0","foo": ["bar"]}] }) }, - "Flattens first script element with extractAllScripts: false": { + 'Flattens first script element with extractAllScripts: false': { input: %( @@ -588,7 +589,7 @@ }), extractAllScripts: false }, - "Flattens targeted script element": { + 'Flattens targeted script element': { input: %( @@ -621,7 +622,7 @@ }), base: "http://example.org/doc#second" }, - "Flattens all script elements by default": { + 'Flattens all script elements by default': { input: %( @@ -656,11 +657,11 @@ {"@id": "_:b2", "ex:bar": "bar"} ] }) - }, + } }.each do |title, params| it(title) do params[:input] = StringIO.new(params[:input]) - params[:input].send(:define_singleton_method, :content_type) {"text/html"} + params[:input].send(:define_singleton_method, :content_type) { "text/html" } run_flatten params.merge(validate: true) end end @@ -668,7 +669,7 @@ context "JSON-LD-star" do { - "node object with @annotation property is ignored without rdfstar option": { + 'node object with @annotation property is ignored without rdfstar option': { input: %({ "@id": "ex:bob", "ex:knows": { @@ -683,7 +684,7 @@ "ex:knows": [{"@id": "ex:fred"}] }]) }, - "value object with @annotation property is ignored without rdfstar option": { + 'value object with @annotation property is ignored without rdfstar option': { input: %({ "@id": "ex:bob", "ex:age": { @@ -697,13 +698,13 @@ "@id": "ex:bob", "ex:age": [{"@value": 23}] }]) - }, + } }.each do |title, params| - it(title) {run_flatten params} + it(title) { run_flatten params } end { - "node with embedded subject having no @id": { + 'node with embedded subject having no @id': { input: %({ "@id": { "ex:prop": "value" @@ -717,7 +718,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having IRI @id": { + 'node with embedded subject having IRI @id': { input: %({ "@id": { "@id": "ex:rei", @@ -733,7 +734,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having BNode @id": { + 'node with embedded subject having BNode @id': { input: %({ "@id": { "@id": "_:rei", @@ -749,7 +750,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having a type": { + 'node with embedded subject having a type': { input: %({ "@id": { "@id": "ex:rei", @@ -765,7 +766,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having an IRI value": { + 'node with embedded subject having an IRI value': { input: %({ "@id": { "@id": "ex:rei", @@ -781,7 +782,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded subject having an BNode value": { + 'node with embedded subject having an BNode value': { input: %({ "@id": { "@id": "ex:rei", @@ -797,7 +798,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with recursive embedded subject": { + 'node with recursive embedded subject': { input: %({ "@id": { "@id": { @@ -819,7 +820,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with embedded object": { + 'node with embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -839,7 +840,7 @@ }] }]) }, - "node with embedded object having properties": { + 'node with embedded object having properties': { input: %({ "@id": "ex:subj", "ex:value": { @@ -866,7 +867,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with recursive embedded object": { + 'node with recursive embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -902,7 +903,7 @@ "ex:prop": [{"@value": "value2"}] }]) }, - "node with @annotation property on value object": { + 'node with @annotation property on value object': { input: %({ "@id": "ex:bob", "ex:age": { @@ -921,7 +922,7 @@ "ex:certainty": [{"@value": 0.8}] }]) }, - "node with @annotation property on node object": { + 'node with @annotation property on node object': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -946,7 +947,7 @@ "ex:certainty": [{"@value": 0.8}] }]) }, - "node with @annotation property multiple values": { + 'node with @annotation property multiple values': { input: %({ "@id": "ex:bob", "ex:name": "Bob", @@ -976,7 +977,7 @@ "ex:source": [{"@id": "http://example.org/"}] }]) }, - "node with @annotation property on embedded subject": { + 'node with @annotation property on embedded subject': { input: %({ "@id": { "@id": "ex:rei", @@ -1004,7 +1005,7 @@ "ex:certainty": [{"@value": 0.8}] }]) }, - "node with @annotation property on embedded object": { + 'node with @annotation property on embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -1036,7 +1037,7 @@ "ex:certainty": [{"@value": 0.8}] }]) }, - "embedded node used as subject in reverse relationship": { + 'embedded node used as subject in reverse relationship': { input: %({ "@context": { "rel": {"@reverse": "ex:rel"} @@ -1057,7 +1058,7 @@ }] }]) }, - "embedded node used as object in reverse relationship": { + 'embedded node used as object in reverse relationship': { input: %({ "@context": { "rel": {"@reverse": "ex:rel"} @@ -1080,7 +1081,7 @@ "ex:prop": [{"@id": "ex:value2"}] }]) }, - "node with @annotation property on node object with reverse relationship": { + 'node with @annotation property on node object with reverse relationship': { input: %({ "@context": { "knownBy": {"@reverse": "ex:knows"} @@ -1108,7 +1109,7 @@ "ex:certainty": [{"@value": 0.8}] }]) }, - "reverse relationship inside annotation": { + 'reverse relationship inside annotation': { input: %({ "@context": { "claims": {"@reverse": "ex:claims", "@type": "@id"} @@ -1141,7 +1142,7 @@ }] }]) }, - "embedded node with annotation on value object": { + 'embedded node with annotation on value object': { input: %({ "@context": { "@base": "http://example.org/", @@ -1175,25 +1176,29 @@ }]) } }.each do |title, params| - it(title) {run_flatten params.merge(rdfstar: true)} + it(title) { run_flatten params.merge(rdfstar: true) } end end def run_flatten(params) - input, output, context = params[:input], params[:output], params[:context] - input = ::JSON.parse(input) if input.is_a?(String) - output = ::JSON.parse(output) if output.is_a?(String) - context = ::JSON.parse(context) if context.is_a?(String) + input = params[:input] + output = params[:output] + context = params[:context] + input = JSON.parse(input) if input.is_a?(String) + output = JSON.parse(output) if output.is_a?(String) + context = JSON.parse(context) if context.is_a?(String) params[:base] ||= nil pending params.fetch(:pending, "test implementation") unless input if params[:exception] - expect {JSON::LD::API.flatten(input, context, logger: logger, **params)}.to raise_error(params[:exception]) + expect { JSON::LD::API.flatten(input, context, logger: logger, **params) }.to raise_error(params[:exception]) else jld = nil if params[:write] - expect{jld = JSON::LD::API.flatten(input, context, logger: logger, **params)}.to write(params[:write]).to(:error) + expect do + jld = JSON::LD::API.flatten(input, context, logger: logger, **params) + end.to write(params[:write]).to(:error) else - expect{jld = JSON::LD::API.flatten(input, context, logger: logger, **params)}.not_to write.to(:error) + expect { jld = JSON::LD::API.flatten(input, context, logger: logger, **params) }.not_to write.to(:error) end jld = remap_bnodes(jld, output) if params[:remap_nodes] diff --git a/spec/format_spec.rb b/spec/format_spec.rb index f23cb975..179ff418 100644 --- a/spec/format_spec.rb +++ b/spec/format_spec.rb @@ -1,20 +1,21 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/spec/format' describe JSON::LD::Format do it_behaves_like 'an RDF::Format' do - let(:format_class) {JSON::LD::Format} + let(:format_class) { described_class } end describe ".for" do formats = [ :jsonld, "etc/doap.jsonld", - {file_name: 'etc/doap.jsonld'}, - {file_extension: 'jsonld'}, - {content_type: 'application/ld+json'}, - {content_type: 'application/x-ld+json'}, + { file_name: 'etc/doap.jsonld' }, + { file_extension: 'jsonld' }, + { content_type: 'application/ld+json' }, + { content_type: 'application/x-ld+json' } ].each do |arg| it "discovers with #{arg.inspect}" do expect(RDF::Format.for(arg)).to eq described_class @@ -22,32 +23,32 @@ end { - jsonld: '{"@context" => "foo"}', - context: %({\n"@context": {), - id: %({\n"@id": {), - type: %({\n"@type": {), + jsonld: '{"@context" => "foo"}', + context: %({\n"@context": {), + id: %({\n"@id": {), + type: %({\n"@type": {) }.each do |sym, str| it "detects #{sym}" do - expect(described_class.for {str}).to eq described_class + expect(described_class.for { str }).to eq described_class end end - it "should discover 'jsonld'" do + it "discovers 'jsonld'" do expect(RDF::Format.for(:jsonld).reader).to eq JSON::LD::Reader end end describe "#to_sym" do - specify {expect(described_class.to_sym).to eq :jsonld} + specify { expect(described_class.to_sym).to eq :jsonld } end describe "#to_uri" do - specify {expect(described_class.to_uri).to eq RDF::URI('http://www.w3.org/ns/formats/JSON-LD')} + specify { expect(described_class.to_uri).to eq RDF::URI('http://www.w3.org/ns/formats/JSON-LD') } end describe ".detect" do { - jsonld: '{"@context" => "foo"}', + jsonld: '{"@context" => "foo"}' }.each do |sym, str| it "detects #{sym}" do expect(described_class.detect(str)).to be_truthy @@ -55,14 +56,14 @@ end { - n3: "@prefix foo: .\nfoo:bar = { } .", - nquads: " . ", - rdfxml: '', - rdfa: '
', - microdata: '
', - ntriples: "
.", + n3: "@prefix foo: .\nfoo:bar = { } .", + nquads: " . ", + rdfxml: '', + rdfa: '
', + microdata: '
', + ntriples: "
.", multi_line: '\n \n "literal"\n .', - turtle: "@prefix foo: .\n foo:a foo:b .", + turtle: "@prefix foo: .\n foo:a foo:b ." }.each do |sym, str| it "does not detect #{sym}" do expect(described_class.detect(str)).to be_falsey @@ -72,43 +73,66 @@ describe ".cli_commands", skip: Gem.win_platform? do require 'rdf/cli' - let(:ttl) {File.expand_path("../test-files/test-1-rdf.ttl", __FILE__)} - let(:json) {File.expand_path("../test-files/test-1-input.jsonld", __FILE__)} - let(:context) {File.expand_path("../test-files/test-1-context.jsonld", __FILE__)} + let(:ttl) { File.expand_path('test-files/test-1-rdf.ttl', __dir__) } + let(:json) { File.expand_path('test-files/test-1-input.jsonld', __dir__) } + let(:context) { File.expand_path('test-files/test-1-context.jsonld', __dir__) } describe "#expand" do it "expands RDF" do - expect {RDF::CLI.exec(["expand", ttl], format: :ttl, output_format: :jsonld)}.to write.to(:output) + expect { RDF::CLI.exec(["expand", ttl], format: :ttl, output_format: :jsonld) }.to write.to(:output) end + it "expands JSON" do - expect {RDF::CLI.exec(["expand", json], format: :jsonld, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["expand", json], format: :jsonld, output_format: :jsonld, validate: false) + end.to write.to(:output) end end describe "#compact" do it "compacts RDF" do - expect {RDF::CLI.exec(["compact", ttl], context: context, format: :ttl, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["compact", ttl], context: context, format: :ttl, output_format: :jsonld, + validate: false) + end.to write.to(:output) end + it "compacts JSON" do - expect {RDF::CLI.exec(["compact", json], context: context, format: :jsonld, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["compact", json], context: context, format: :jsonld, output_format: :jsonld, + validate: false) + end.to write.to(:output) end end describe "#flatten" do it "flattens RDF" do - expect {RDF::CLI.exec(["flatten", ttl], context: context, format: :ttl, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["flatten", ttl], context: context, format: :ttl, output_format: :jsonld, + validate: false) + end.to write.to(:output) end + it "flattens JSON" do - expect {RDF::CLI.exec(["flatten", json], context: context, format: :jsonld, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["flatten", json], context: context, format: :jsonld, output_format: :jsonld, + validate: false) + end.to write.to(:output) end end describe "#frame" do it "frames RDF" do - expect {RDF::CLI.exec(["frame", ttl], frame: context, format: :ttl, output_format: :jsonld)}.to write.to(:output) + expect do + RDF::CLI.exec(["frame", ttl], frame: context, format: :ttl, output_format: :jsonld) + end.to write.to(:output) end + it "frames JSON" do - expect {RDF::CLI.exec(["frame", json], frame: context, format: :jsonld, output_format: :jsonld, validate: false)}.to write.to(:output) + expect do + RDF::CLI.exec(["frame", json], frame: context, format: :jsonld, output_format: :jsonld, + validate: false) + end.to write.to(:output) end end end diff --git a/spec/frame_spec.rb b/spec/frame_spec.rb index 8f3ad7f5..72ed82cd 100644 --- a/spec/frame_spec.rb +++ b/spec/frame_spec.rb @@ -1,12 +1,13 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } describe ".frame" do { - "exact @type match": { + 'exact @type match': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" @@ -30,7 +31,7 @@ }] }) }, - "wildcard @type match": { + 'wildcard @type match': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": {} @@ -57,7 +58,7 @@ }] }) }, - "match none @type match": { + 'match none @type match': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": [] @@ -82,7 +83,7 @@ }] }) }, - "multiple matches on @type": { + 'multiple matches on @type': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" @@ -114,7 +115,7 @@ }] }) }, - "single @id match": { + 'single @id match': { frame: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1" @@ -138,7 +139,7 @@ }] }) }, - "multiple @id match": { + 'multiple @id match': { frame: %({ "@context": {"ex": "http://example.org/"}, "@id": ["ex:Sub1", "ex:Sub2"] @@ -169,7 +170,7 @@ }] }) }, - "wildcard and match none": { + 'wildcard and match none': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": [], @@ -196,7 +197,7 @@ }] }) }, - "match on any property if @requireAll is false": { + 'match on any property if @requireAll is false': { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": false, @@ -227,7 +228,7 @@ }] }) }, - "match on defeaults if @requireAll is true and at least one property matches": { + 'match on defeaults if @requireAll is true and at least one property matches': { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, @@ -271,7 +272,7 @@ }] }) }, - "match with @requireAll with one default": { + 'match with @requireAll with one default': { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, @@ -372,7 +373,7 @@ }] }) }, - "issue #40 - example": { + 'issue #40 - example': { frame: %({ "@context": { "@version": 1.1, @@ -417,18 +418,18 @@ }), processingMode: 'json-ld-1.1' }, - "implicitly includes unframed properties (default @explicit false)": { + 'implicitly includes unframed properties (default @explicit false)': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" }), - input: %q({ + input: '{ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} - }), + }', output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ @@ -439,19 +440,19 @@ }] }) }, - "explicitly includes unframed properties @explicit false": { + 'explicitly includes unframed properties @explicit false': { frame: %({ "@context": {"ex": "http://example.org/"}, "@explicit": false, "@type": "ex:Type1" }), - input: %q({ + input: '{ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} - }), + }', output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ @@ -462,7 +463,7 @@ }] }) }, - "explicitly excludes unframed properties (@explicit: true)": { + 'explicitly excludes unframed properties (@explicit: true)': { frame: %({ "@context": {"ex": "http://example.org/"}, "@explicit": true, @@ -483,7 +484,7 @@ }] }) }, - "non-existent framed properties create null property": { + 'non-existent framed properties create null property': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1", @@ -511,7 +512,7 @@ }] }) }, - "non-existent framed properties create default property": { + 'non-existent framed properties create default property': { frame: %({ "@context": { "ex": "http://example.org/", @@ -541,7 +542,7 @@ }] }) }, - "default value for @type": { + 'default value for @type': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": {"@default": "ex:Foo"}, @@ -561,7 +562,7 @@ }] }) }, - "mixed content": { + 'mixed content': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:mixed": {"@embed": "@never"} @@ -585,7 +586,7 @@ }] }) }, - "no embedding (@embed: @never)": { + 'no embedding (@embed: @never)': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:embed": {"@embed": "@never"} @@ -606,7 +607,7 @@ }] }) }, - "first embed (@embed: @once)": { + 'first embed (@embed: @once)': { frame: %({ "@context": {"ex": "http://www.example.com/#"}, "@type": "ex:Thing", @@ -632,7 +633,7 @@ }), ordered: true }, - "always embed (@embed: @always)": { + 'always embed (@embed: @always)': { frame: %({ "@context": {"ex": "http://www.example.com/#"}, "@type": "ex:Thing", @@ -657,7 +658,7 @@ ] }) }, - "mixed list": { + 'mixed list': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:mixedlist": {} @@ -687,7 +688,7 @@ }] }) }, - "framed list": { + 'framed list': { frame: %({ "@context": { "ex": "http://example.org/", @@ -722,7 +723,7 @@ }] }) }, - "presentation example": { + 'presentation example': { frame: %({ "@context": { "primaryTopic": { @@ -769,7 +770,7 @@ }] }) }, - "microdata manifest": { + 'microdata manifest': { frame: %({ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", @@ -792,7 +793,7 @@ } }] }), - input: %q({ + input: '{ "@context": { "md": "http://www.w3.org/ns/md#", "mf": "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#", @@ -817,7 +818,7 @@ "mq:data": {"@id": "http://www.w3.org/TR/microdata-rdf/tests/0001.html"}, "mq:query": {"@id": "http://www.w3.org/TR/microdata-rdf/tests/0001.ttl"} }] - }), + }', output: %({ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", @@ -848,7 +849,7 @@ }), processingMode: 'json-ld-1.1' }, - "library": { + library: { frame: %({ "@context": { "dc": "http://purl.org/dc/elements/1.1/", @@ -917,7 +918,7 @@ describe "@reverse" do { - "embed matched frames with @reverse": { + 'embed matched frames with @reverse': { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1", @@ -950,7 +951,7 @@ }] }) }, - "embed matched frames with reversed property": { + 'embed matched frames with reversed property': { frame: %({ "@context": { "ex": "http://example.org/", @@ -984,7 +985,7 @@ } }] }) - }, + } }.each do |title, params| it title do do_frame(params) @@ -994,7 +995,7 @@ context "omitGraph option" do { - "Defaults to false in 1.0": { + 'Defaults to false in 1.0': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1015,7 +1016,7 @@ }), processingMode: "json-ld-1.0" }, - "Set with option in 1.0": { + 'Set with option in 1.0': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1035,7 +1036,7 @@ processingMode: "json-ld-1.0", omitGraph: true }, - "Defaults to true in 1.1": { + 'Defaults to true in 1.1': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1054,7 +1055,7 @@ }), processingMode: "json-ld-1.1" }, - "Set with option in 1.1": { + 'Set with option in 1.1': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1075,15 +1076,15 @@ }), processingMode: "json-ld-1.1", omitGraph: false - }, + } }.each do |title, params| - it(title) {do_frame(params.merge(pruneBlankNodeIdentifiers: true))} + it(title) { do_frame(params.merge(pruneBlankNodeIdentifiers: true)) } end end context "@included" do { - "Basic Included array": { + 'Basic Included array': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1120,7 +1121,7 @@ "prop": "value" }) }, - "Basic Included object": { + 'Basic Included object': { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] @@ -1155,7 +1156,7 @@ } }) }, - "json.api example": { + 'json.api example': { input: %([{ "@id": "http://example.org/base/1", "@type": ["http://example.org/vocab#articles"], @@ -1272,16 +1273,16 @@ "author": "9", "self": "http://example.com/comments/12" }] - }), - }, + }) + } }.each do |title, params| - it(title) {do_frame(params.merge(processingMode: 'json-ld-1.1'))} + it(title) { do_frame(params.merge(processingMode: 'json-ld-1.1')) } end end describe "node pattern" do { - "matches a deep node pattern": { + 'matches a deep node pattern': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": { @@ -1320,7 +1321,7 @@ } }] }) - }, + } }.each do |title, params| it title do do_frame(params) @@ -1330,7 +1331,7 @@ describe "value pattern" do { - "matches exact values": { + 'matches exact values': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": "P", @@ -1354,7 +1355,7 @@ }] }) }, - "matches wildcard @value": { + 'matches wildcard @value': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}}, @@ -1378,7 +1379,7 @@ }] }) }, - "matches wildcard @type": { + 'matches wildcard @type': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:q": {"@value": "Q", "@type": {}} @@ -1396,7 +1397,7 @@ }] }) }, - "matches wildcard @language": { + 'matches wildcard @language': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:r": {"@value": "R", "@language": {}} @@ -1414,7 +1415,7 @@ }] }) }, - "match none @type": { + 'match none @type': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}, "@type": []}, @@ -1438,7 +1439,7 @@ }] }) }, - "match none @language": { + 'match none @language': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}, "@language": []}, @@ -1462,7 +1463,7 @@ }] }) }, - "matches some @value": { + 'matches some @value': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": ["P", "Q", "R"]}, @@ -1486,7 +1487,7 @@ }] }) }, - "matches some @type": { + 'matches some @type': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:q": {"@value": "Q", "@type": ["ex:q", "ex:Q"]} @@ -1504,7 +1505,7 @@ }] }) }, - "matches some @language": { + 'matches some @language': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:r": {"@value": "R", "@language": ["p", "q", "r"]} @@ -1522,7 +1523,7 @@ }] }) }, - "excludes non-matched values": { + 'excludes non-matched values': { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}}, @@ -1545,7 +1546,7 @@ "ex:r": {"@value": "R", "@language": "R"} }] }) - }, + } }.each do |title, params| it title do do_frame(params) @@ -1555,7 +1556,7 @@ describe "named graphs" do { - "Merge graphs if no outer @graph is used": { + 'Merge graphs if no outer @graph is used': { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class" @@ -1579,7 +1580,7 @@ }), processingMode: 'json-ld-1.1' }, - "Frame default graph if outer @graph is used": { + 'Frame default graph if outer @graph is used': { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", @@ -1611,7 +1612,7 @@ }), processingMode: 'json-ld-1.1' }, - "Merge one graph and preserve another": { + 'Merge one graph and preserve another': { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", @@ -1656,7 +1657,7 @@ }), processingMode: 'json-ld-1.1' }, - "Merge one graph and deep preserve another": { + 'Merge one graph and deep preserve another': { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", @@ -1705,7 +1706,7 @@ }), processingMode: 'json-ld-1.1' }, - "library": { + library: { frame: %({ "@context": {"@vocab": "http://example.org/"}, "@type": "Library", @@ -1758,7 +1759,7 @@ }), processingMode: 'json-ld-1.1' }, - "named graph with @embed: @never": { + 'named graph with @embed: @never': { input: %({ "@id": "ex:cred", "ex:subject": { @@ -1815,7 +1816,7 @@ } }), processingMode: 'json-ld-1.1' - }, + } }.each do |title, params| it title do do_frame(params) @@ -1826,7 +1827,7 @@ describe "prune blank nodes" do { - "preserves single-use bnode identifiers if @version 1.0": { + 'preserves single-use bnode identifiers if @version 1.0': { frame: %({ "@context": { "dc": "http://purl.org/dc/terms/", @@ -1877,7 +1878,7 @@ }), processingMode: 'json-ld-1.0' }, - "preserves single-use bnode identifiers if pruneBlankNodeIdentifiers=false": { + 'preserves single-use bnode identifiers if pruneBlankNodeIdentifiers=false': { frame: %({ "@context": { "dc": "http://purl.org/dc/terms/", @@ -1928,7 +1929,7 @@ }), pruneBlankNodeIdentiers: false }, - "framing with @version: 1.1 prunes identifiers": { + 'framing with @version: 1.1 prunes identifiers': { frame: %({ "@context": { "@version": 1.1, @@ -1985,7 +1986,7 @@ context "problem cases" do { - "pr #20": { + 'pr #20': { frame: %({}), input: %([ { @@ -2019,7 +2020,7 @@ ] }) }, - "issue #28": { + 'issue #28': { frame: %({ "@context": { "rdfs": "http://www.w3.org/2000/01/rdf-schema#", @@ -2074,7 +2075,7 @@ ] }) }, - "PR #663 - Multiple named graphs": { + 'PR #663 - Multiple named graphs': { frame: %({ "@context": { "@vocab": "http://example.com/", @@ -2184,8 +2185,8 @@ }), processingMode: 'json-ld-1.1' }, - "w3c/json-ld-framing#5": { - frame: %({ + 'w3c/json-ld-framing#5': { + frame: %({ "@context" : { "@vocab" : "http://purl.bdrc.io/ontology/core/", "taxSubclassOf" : { @@ -2257,7 +2258,7 @@ }), processingMode: 'json-ld-1.1' }, - "issue json-ld-framing#30": { + 'issue json-ld-framing#30': { input: %({ "@context": {"eg": "https://example.org/ns/"}, "@id": "https://example.org/what", @@ -2277,7 +2278,7 @@ }] }) }, - "issue json-ld-framing#64": { + 'issue json-ld-framing#64': { input: %({ "@context": { "@version": 1.1, @@ -2301,7 +2302,7 @@ "Production": { "@context": { "part": { - "@type": "@id", + "@type": "@id", "@container": "@set" } } @@ -2316,7 +2317,7 @@ "Production": { "@context": { "part": { - "@type": "@id", + "@type": "@id", "@container": "@set" } } @@ -2335,7 +2336,7 @@ }), processingMode: "json-ld-1.1" }, - "issue json-ld-framing#27": { + 'issue json-ld-framing#27': { input: %({ "@id": "ex:cred", "ex:subject": { @@ -2395,7 +2396,7 @@ }), processingMode: "json-ld-1.1" }, - "missing types": { + 'missing types': { input: %({ "@context": { "ex": "http://example.com#", @@ -2463,7 +2464,7 @@ }), processingMode: "json-ld-1.1" }, - "issue #142": { + 'issue #142': { input: %({ "@context":{ "ex":"http://example.org/vocab#", @@ -2504,7 +2505,7 @@ "publisher": "JANE" } }), - processingMode: "json-ld-1.1" + processingMode: "json-ld-1.1" } }.each do |title, params| it title do @@ -2514,28 +2515,28 @@ end def do_frame(params) - begin - 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, **params)}.to write(params[:write]).to(:error) - else - expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.not_to write.to(:error) - end - expect(jld).to produce_jsonld(output, logger) - - # Compare expanded jld/output too to make sure list values remain ordered - exp_jld = JSON::LD::API.expand(jld, processingMode: 'json-ld-1.1') - exp_output = JSON::LD::API.expand(output, processingMode: 'json-ld-1.1') - expect(exp_jld).to produce_jsonld(exp_output, logger) - rescue JSON::LD::JsonLdError => e - fail("#{e.class}: #{e.message}\n" + - "#{logger}\n" + - "Backtrace:\n#{e.backtrace.join("\n")}") + input = params[:input] + frame = params[:frame] + output = 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, **params) }.to write(params[:write]).to(:error) + else + expect { jld = JSON::LD::API.frame(input, frame, logger: logger, **params) }.not_to write.to(:error) end + expect(jld).to produce_jsonld(output, logger) + + # Compare expanded jld/output too to make sure list values remain ordered + exp_jld = JSON::LD::API.expand(jld, processingMode: 'json-ld-1.1') + exp_output = JSON::LD::API.expand(output, processingMode: 'json-ld-1.1') + expect(exp_jld).to produce_jsonld(exp_output, logger) + rescue JSON::LD::JsonLdError => e + raise("#{e.class}: #{e.message}\n" \ + "#{logger}\n" \ + "Backtrace:\n#{e.backtrace.join("\n")}") end end diff --git a/spec/from_rdf_spec.rb b/spec/from_rdf_spec.rb index ca9148ea..f9a61ec8 100644 --- a/spec/from_rdf_spec.rb +++ b/spec/from_rdf_spec.rb @@ -1,148 +1,149 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/spec/writer' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } describe ".fromRdf" do context "simple tests" do it "One subject IRI object" do input = %( .) expect(serialize(input)).to produce_jsonld([ - { - '@id' => "http://a/b", - "http://a/c" => [{"@id" => "http://a/d"}] - } - ], logger) + { + '@id' => "http://a/b", + "http://a/c" => [{ "@id" => "http://a/d" }] + } + ], logger) end - it "should generate object list" do + it "generates object list" do input = %(@prefix : . :b :c :d, :e .) - expect(serialize(input)). - to produce_jsonld([{ - '@id' => "http://example.com/b", - "http://example.com/c" => [ - {"@id" => "http://example.com/d"}, - {"@id" => "http://example.com/e"} - ] - } - ], logger) + expect(serialize(input)) + .to produce_jsonld([{ + '@id' => "http://example.com/b", + "http://example.com/c" => [ + { "@id" => "http://example.com/d" }, + { "@id" => "http://example.com/e" } + ] + }], logger) end - - it "should generate property list" do + + it "generates property list" do input = %(@prefix : . :b :c :d; :e :f .) - expect(serialize(input)). - to produce_jsonld([{ - '@id' => "http://example.com/b", - "http://example.com/c" => [{"@id" => "http://example.com/d"}], - "http://example.com/e" => [{"@id" => "http://example.com/f"}] - } - ], logger) + expect(serialize(input)) + .to produce_jsonld([{ + '@id' => "http://example.com/b", + "http://example.com/c" => [{ "@id" => "http://example.com/d" }], + "http://example.com/e" => [{ "@id" => "http://example.com/f" }] + }], logger) end - + it "serializes multiple subjects" do - input = %q( + input = ' @prefix : . @prefix dc: . a :TestCase . a :TestCase . - ) - expect(serialize(input)). - to produce_jsonld([ - {'@id' => "test-cases/0001", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]}, - {'@id' => "test-cases/0002", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]}, - ], logger) + ' + expect(serialize(input)) + .to produce_jsonld([ + { '@id' => "test-cases/0001", + '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"] }, + { '@id' => "test-cases/0002", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"] } + ], logger) end end - + context "literals" do context "coercion" do it "typed literal" do input = %(@prefix ex: . ex:a ex:b "foo"^^ex:d .) expect(serialize(input)).to produce_jsonld([ - { - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "foo", "@type" => "http://example.com/d"}] - } - ], logger) + { + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "foo", + "@type" => "http://example.com/d" }] + } + ], logger) end it "integer" do input = %(@prefix ex: . ex:a ex:b 1 .) expect(serialize(input, useNativeTypes: true)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => 1}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => 1 }] }], logger) end it "integer (non-native)" do input = %(@prefix ex: . ex:a ex:b 1 .) expect(serialize(input, useNativeTypes: false)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "1","@type" => "http://www.w3.org/2001/XMLSchema#integer"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "1", "@type" => "http://www.w3.org/2001/XMLSchema#integer" }] }], logger) end it "boolean" do input = %(@prefix ex: . ex:a ex:b true .) expect(serialize(input, useNativeTypes: true)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => true}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => true }] }], logger) end it "boolean (non-native)" do input = %(@prefix ex: . ex:a ex:b true .) expect(serialize(input, useNativeTypes: false)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "true","@type" => "http://www.w3.org/2001/XMLSchema#boolean"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "true", "@type" => "http://www.w3.org/2001/XMLSchema#boolean" }] }], logger) end it "decmal" do input = %(@prefix ex: . ex:a ex:b 1.0 .) expect(serialize(input, useNativeTypes: true)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "1.0", "@type" => "http://www.w3.org/2001/XMLSchema#decimal"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "1.0", "@type" => "http://www.w3.org/2001/XMLSchema#decimal" }] }], logger) end it "double" do input = %(@prefix ex: . ex:a ex:b 1.0e0 .) expect(serialize(input, useNativeTypes: true)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => 1.0E0}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => 1.0E0 }] }], logger) end it "double (non-native)" do input = %(@prefix ex: . ex:a ex:b 1.0e0 .) expect(serialize(input, useNativeTypes: false)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "1.0E0","@type" => "http://www.w3.org/2001/XMLSchema#double"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "1.0E0", "@type" => "http://www.w3.org/2001/XMLSchema#double" }] }], logger) end end context "datatyped (non-native)" do { - integer: 1, - unsignedInteger: 1, + integer: 1, + unsignedInteger: 1, nonNegativeInteger: 1, - float: 1, + float: 1, nonPositiveInteger: -1, - negativeInteger: -1, + negativeInteger: -1 }.each do |t, v| - it "#{t}" do + it t.to_s do input = %( @prefix xsd: . @prefix ex: . ex:a ex:b "#{v}"^^xsd:#{t} . ) expect(serialize(input, useNativeTypes: false)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "#{v}","@type" => "http://www.w3.org/2001/XMLSchema##{t}"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => v.to_s, "@type" => "http://www.w3.org/2001/XMLSchema##{t}" }] }], logger) end end @@ -151,25 +152,25 @@ it "encodes language literal" do input = %(@prefix ex: . ex:a ex:b "foo"@en-us .) expect(serialize(input)).to produce_jsonld([{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@value" => "foo", "@language" => "en-us"}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@value" => "foo", "@language" => "en-us" }] }], logger) end context "with @type: @json" do { - "true": { + true => { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}] }]), - input:%( + input: %( @prefix ex: . @prefix rdf: . ex:id ex:bool "true"^^rdf:JSON . ) }, - "false": { + false => { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}] @@ -180,7 +181,7 @@ ex:id ex:bool "false"^^rdf:JSON . ) }, - "double": { + double: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#double": [{"@value": 1.23E0, "@type": "@json"}] @@ -191,7 +192,7 @@ ex:id ex:double "1.23E0"^^rdf:JSON . ) }, - "double-zero": { + 'double-zero': { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#double": [{"@value": 0, "@type": "@json"}] @@ -202,7 +203,7 @@ ex:id ex:double "0.0E0"^^rdf:JSON . ) }, - "integer": { + integer: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#integer": [{"@value": 123, "@type": "@json"}] @@ -213,7 +214,7 @@ ex:id ex:integer "123"^^rdf:JSON . ) }, - "string": { + string: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#string": [{ @@ -227,7 +228,7 @@ ex:id ex:string "\\"string\\""^^rdf:JSON . ) }, - "null": { + null: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#null": [{ @@ -241,7 +242,7 @@ ex:id ex:null "null"^^rdf:JSON . ) }, - "object": { + object: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}] @@ -252,7 +253,7 @@ ex:id ex:object """{"foo":"bar"}"""^^rdf:JSON . ) }, - "array": { + array: { output: %([{ "@id": "http://example.org/vocab#id", "http://example.org/vocab#array": [{"@value": [{"foo": "bar"}], "@type": "@json"}] @@ -262,223 +263,224 @@ @prefix rdf: . ex:id ex:array """[{"foo":"bar"}]"""^^rdf:JSON . ) - }, + } }.each do |title, params| params[:input] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:input]) - it(title) {do_fromRdf(processingMode: "json-ld-1.1", **params)} + it(title) { do_fromRdf(processingMode: "json-ld-1.1", **params) } end end context "extendedRepresentation: true" do { - "true": { + true => { output: [{ - "@id" => "http://example.org/vocab#id", - "http://example.org/vocab#bool" => [{"@value" => RDF::Literal(true)}] - }], - input:%( + "@id" => "http://example.org/vocab#id", + "http://example.org/vocab#bool" => [{ "@value" => RDF::Literal(true) }] + }], + input: %( @prefix ex: . @prefix rdf: . ex:id ex:bool true . ) }, - "false": { + false => { output: [{ - "@id" => "http://example.org/vocab#id", - "http://example.org/vocab#bool" => [{"@value" => RDF::Literal(false)}] - }], + "@id" => "http://example.org/vocab#id", + "http://example.org/vocab#bool" => [{ "@value" => RDF::Literal(false) }] + }], input: %( @prefix ex: . @prefix rdf: . ex:id ex:bool false . ) }, - "double": { + double: { output: [{ - "@id" => "http://example.org/vocab#id", - "http://example.org/vocab#double" => [{"@value" => RDF::Literal(1.23E0)}] - }], + "@id" => "http://example.org/vocab#id", + "http://example.org/vocab#double" => [{ "@value" => RDF::Literal(1.23E0) }] + }], input: %( @prefix ex: . @prefix rdf: . ex:id ex:double 1.23E0 . ) }, - "double-zero": { + 'double-zero': { output: [{ - "@id" => "http://example.org/vocab#id", - "http://example.org/vocab#double" => [{"@value" => RDF::Literal(0, datatype: RDF::XSD.double)}] - }], + "@id" => "http://example.org/vocab#id", + "http://example.org/vocab#double" => [{ "@value" => RDF::Literal(0, datatype: RDF::XSD.double) }] + }], input: %( @prefix ex: . @prefix rdf: . ex:id ex:double 0.0E0 . ) }, - "integer": { + integer: { output: [{ - "@id" => "http://example.org/vocab#id", - "http://example.org/vocab#integer" => [{"@value" => RDF::Literal(123)}] - }], + "@id" => "http://example.org/vocab#id", + "http://example.org/vocab#integer" => [{ "@value" => RDF::Literal(123) }] + }], input: %( @prefix ex: . @prefix rdf: . ex:id ex:integer 123 . ) - }, + } }.each do |title, params| params[:input] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:input]) it(title) { do_fromRdf(processingMode: "json-ld-1.1", - useNativeTypes: true, - extendedRepresentation: true, - **params)} + useNativeTypes: true, + extendedRepresentation: true, + **params) + } end end end context "anons" do - it "should generate bare anon" do + it "generates bare anon" do input = %(@prefix : . _:a :a :b .) expect(serialize(input)).to produce_jsonld([ - { - "@id" => "_:a", - "http://example.com/a" => [{"@id" => "http://example.com/b"}] - } - ], logger) + { + "@id" => "_:a", + "http://example.com/a" => [{ "@id" => "http://example.com/b" }] + } + ], logger) end - - it "should generate anon as object" do + + it "generates anon as object" do input = %(@prefix : . :a :b _:a . _:a :c :d .) expect(serialize(input)).to produce_jsonld([ - { - "@id" => "_:a", - "http://example.com/c" => [{"@id" => "http://example.com/d"}] - }, - { - "@id" => "http://example.com/a", - "http://example.com/b" => [{"@id" => "_:a"}] - } - ], logger) + { + "@id" => "_:a", + "http://example.com/c" => [{ "@id" => "http://example.com/d" }] + }, + { + "@id" => "http://example.com/a", + "http://example.com/b" => [{ "@id" => "_:a" }] + } + ], logger) end end context "lists" do { "literal list" => { - input: %q( + input: ' @prefix : . @prefix rdf: . :a :b ("apple" "banana") . - ), + ', output: [{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{ + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@list" => [ - {"@value" => "apple"}, - {"@value" => "banana"} + { "@value" => "apple" }, + { "@value" => "banana" } ] }] }] }, "iri list" => { - input: %q(@prefix : . :a :b (:c) .), + input: '@prefix : . :a :b (:c) .', output: [{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{ + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@list" => [ - {"@id" => "http://example.com/c"} + { "@id" => "http://example.com/c" } ] }] }] }, "empty list" => { - input: %q(@prefix : . :a :b () .), + input: '@prefix : . :a :b () .', output: [{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@list" => []}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@list" => [] }] }] }, "single element list" => { - input: %q(@prefix : . :a :b ( "apple" ) .), + input: '@prefix : . :a :b ( "apple" ) .', output: [{ - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@list" => [{"@value" => "apple"}]}] + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@list" => [{ "@value" => "apple" }] }] }] }, "single element list without @type" => { - input: %q(@prefix : . :a :b ( _:a ) . _:a :b "foo" .), + input: '@prefix : . :a :b ( _:a ) . _:a :b "foo" .', output: [ { - '@id' => "_:a", - "http://example.com/b" => [{"@value" => "foo"}] + '@id' => "_:a", + "http://example.com/b" => [{ "@value" => "foo" }] }, { - '@id' => "http://example.com/a", - "http://example.com/b" => [{"@list" => [{"@id" => "_:a"}]}] - }, + '@id' => "http://example.com/a", + "http://example.com/b" => [{ "@list" => [{ "@id" => "_:a" }] }] + } ] }, "multiple graphs with shared BNode" => { - input: %q( + input: ' _:z0 . _:z0 "cell-A" . _:z0 _:z1 . _:z1 "cell-B" . _:z1 . _:z1 . - ), + ', output: [{ "@id" => "http://www.example.com/G", "@graph" => [{ "@id" => "_:z0", - "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{"@value" => "cell-A"}], - "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{"@id" => "_:z1"}] + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{ "@value" => "cell-A" }], + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{ "@id" => "_:z1" }] }, { "@id" => "_:z1", - "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{"@value" => "cell-B"}], - "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{"@list" => []}] + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{ "@value" => "cell-B" }], + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{ "@list" => [] }] }, { "@id" => "http://www.example.com/z", - "http://www.example.com/q" => [{"@id" => "_:z0"}] + "http://www.example.com/q" => [{ "@id" => "_:z0" }] }] }, - { - "@id" => "http://www.example.com/G1", - "@graph" => [{ - "@id" => "http://www.example.com/x", - "http://www.example.com/p" => [{"@id" => "_:z1"}] - }] - }], + { + "@id" => "http://www.example.com/G1", + "@graph" => [{ + "@id" => "http://www.example.com/x", + "http://www.example.com/p" => [{ "@id" => "_:z1" }] + }] + }], reader: RDF::NQuads::Reader }, "multiple graphs with shared BNode (at head)" => { - input: %q( + input: ' _:z0 . _:z0 "cell-A" . _:z0 _:z1 . _:z1 "cell-B" . _:z1 . _:z0 . - ), + ', output: [{ "@id" => "http://www.example.com/G", "@graph" => [{ "@id" => "_:z0", - "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{"@value" => "cell-A"}], - "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{"@list" => [{ "@value" => "cell-B" }]}] + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first" => [{ "@value" => "cell-A" }], + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest" => [{ "@list" => [{ "@value" => "cell-B" }] }] }, { "@id" => "http://www.example.com/z", - "http://www.example.com/q" => [{"@id" => "_:z0"}] + "http://www.example.com/q" => [{ "@id" => "_:z0" }] }] }, - { - "@id" => "http://www.example.com/G1", - "@graph" => [{ - "@id" => "http://www.example.com/z", - "http://www.example.com/q" => [{"@id" => "_:z0"}] - }] - }], + { + "@id" => "http://www.example.com/G1", + "@graph" => [{ + "@id" => "http://www.example.com/z", + "http://www.example.com/q" => [{ "@id" => "_:z0" }] + }] + }], reader: RDF::NQuads::Reader }, "@list containing empty @list" => { @@ -552,12 +554,12 @@ reader: RDF::NQuads::Reader } }.each do |name, params| - it "#{name}" do + it name.to_s do do_fromRdf(params) end end end - + context "quads" do { "simple named graph" => { @@ -569,9 +571,9 @@ "@id" => "http://example.com/U", "@graph" => [{ "@id" => "http://example.com/a", - "http://example.com/b" => [{"@id" => "http://example.com/c"}] + "http://example.com/b" => [{ "@id" => "http://example.com/c" }] }] - }, + } ] }, "with properties" => { @@ -584,9 +586,9 @@ "@id" => "http://example.com/U", "@graph" => [{ "@id" => "http://example.com/a", - "http://example.com/b" => [{"@id" => "http://example.com/c"}] + "http://example.com/b" => [{ "@id" => "http://example.com/c" }] }], - "http://example.com/d" => [{"@id" => "http://example.com/e"}] + "http://example.com/d" => [{ "@id" => "http://example.com/e" }] } ] }, @@ -604,9 +606,9 @@ "@id" => "http://example.com/U", "@graph" => [{ "@id" => "http://example.com/a", - "http://example.com/b" => [{"@list" => [{"@id" => "http://example.com/c"}]}] + "http://example.com/b" => [{ "@list" => [{ "@id" => "http://example.com/c" }] }] }], - "http://example.com/d" => [{"@list" => [{"@id" => "http://example.com/e"}]}] + "http://example.com/d" => [{ "@list" => [{ "@id" => "http://example.com/e" }] }] } ] }, @@ -626,7 +628,7 @@ { "@id" => "http://example.com/a", "http://example.com/b" => [{ - "@list" => [{"@id" => "http://example.com/c"}] + "@list" => [{ "@id" => "http://example.com/c" }] }] } ] @@ -637,15 +639,15 @@ { "@id" => "http://example.com/a", "http://example.com/b" => [{ - "@list" => [{"@id" => "http://example.com/e"}] + "@list" => [{ "@id" => "http://example.com/e" }] }] } ] } ] - }, + } }.each_pair do |name, params| - it "#{name}" do + it name.to_s do do_fromRdf(params.merge(reader: RDF::NQuads::Reader)) end end @@ -654,51 +656,51 @@ context "@direction" do context "rdfDirection: null" do { - "no language rtl datatype": { - input: %q( + 'no language rtl datatype': { + input: ' "no language"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "no language", "@type": "https://www.w3.org/ns/i18n#_rtl"}] - }]), + }]' }, - "no language rtl compound-literal": { - input: %q( + 'no language rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "no language"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@id": "_:cl1"}] }, { "@id": "_:cl1", "http://www.w3.org/1999/02/22-rdf-syntax-ns#value": [{"@value": "no language"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#direction": [{"@value": "rtl"}] - }]), + }]' }, - "en-US rtl datatype": { - input: %q( + 'en-US rtl datatype': { + input: ' "en-US"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "en-US", "@type": "https://www.w3.org/ns/i18n#en-us_rtl"}] - }]), + }]' }, - "en-US rtl compound-literal": { - input: %q( + 'en-US rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "en-US"; rdf:language "en-us"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@id": "_:cl1"}] }, { @@ -706,7 +708,7 @@ "http://www.w3.org/1999/02/22-rdf-syntax-ns#value": [{"@value": "en-US"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#language": [{"@value": "en-us"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#direction": [{"@value": "rtl"}] - }]), + }]' } }.each_pair do |name, params| it name do @@ -717,51 +719,51 @@ context "rdfDirection: i18n-datatype" do { - "no language rtl datatype": { - input: %q( + 'no language rtl datatype': { + input: ' "no language"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "no language", "@direction": "rtl"}] - }]), + }]' }, - "no language rtl compound-literal": { - input: %q( + 'no language rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "no language"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@id": "_:cl1"}] }, { "@id": "_:cl1", "http://www.w3.org/1999/02/22-rdf-syntax-ns#value": [{"@value": "no language"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#direction": [{"@value": "rtl"}] - }]), + }]' }, - "en-US rtl datatype": { - input: %q( + 'en-US rtl datatype': { + input: ' "en-US"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "en-US", "@language": "en-US", "@direction": "rtl"}] - }]), + }]' }, - "en-US rtl compound-literal": { - input: %q( + 'en-US rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "en-US"; rdf:language "en-US"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@id": "_:cl1"}] }, { @@ -769,65 +771,67 @@ "http://www.w3.org/1999/02/22-rdf-syntax-ns#value": [{"@value": "en-US"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#language": [{"@value": "en-US"}], "http://www.w3.org/1999/02/22-rdf-syntax-ns#direction": [{"@value": "rtl"}] - }]), + }]' } }.each_pair do |name, params| it name do - do_fromRdf(params.merge(reader: RDF::Turtle::Reader, rdfDirection: 'i18n-datatype', processingMode: 'json-ld-1.1')) + do_fromRdf(params.merge(reader: RDF::Turtle::Reader, rdfDirection: 'i18n-datatype', + processingMode: 'json-ld-1.1')) end end end context "rdfDirection: compound-literal" do { - "no language rtl datatype": { - input: %q( + 'no language rtl datatype': { + input: ' "no language"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "no language", "@type": "https://www.w3.org/ns/i18n#_rtl"}] - }]), + }]' }, - "no language rtl compound-literal": { - input: %q( + 'no language rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "no language"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "no language", "@direction": "rtl"}] - }]), + }]' }, - "en-US rtl datatype": { - input: %q( + 'en-US rtl datatype': { + input: ' "en-US"^^ . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "en-US", "@type": "https://www.w3.org/ns/i18n#en-us_rtl"}] - }]), + }]' }, - "en-US rtl compound-literal": { - input: %q( + 'en-US rtl compound-literal': { + input: ' @prefix rdf: . _:cl1 . _:cl1 rdf:value "en-US"; rdf:language "en-us"; rdf:direction "rtl" . - ), - output: %q([{ + ', + output: '[{ "@id": "http://example.com/a", "http://example.org/label": [{"@value": "en-US", "@language": "en-us", "@direction": "rtl"}] - }]), + }]' } }.each_pair do |name, params| it name do - do_fromRdf(params.merge(reader: RDF::Turtle::Reader, rdfDirection: 'compound-literal', processingMode: 'json-ld-1.1')) + do_fromRdf(params.merge(reader: RDF::Turtle::Reader, rdfDirection: 'compound-literal', + processingMode: 'json-ld-1.1')) end end end @@ -835,14 +839,16 @@ context "RDF-star" do { - "subject-iii": { + 'subject-iii': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "http://example/s1", @@ -851,14 +857,16 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "subject-iib": { + 'subject-iib': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1')), + RDF::Node.new('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "http://example/s1", @@ -867,14 +875,16 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "subject-iil": { + 'subject-iil': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1')), + RDF::Literal('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "http://example/s1", @@ -883,14 +893,16 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "subject-bii": { + 'subject-bii': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "_:s1", @@ -899,13 +911,15 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "subject-bib": { + 'subject-bib': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1')), - RDF::URI('http://example/p'), RDF::URI('http://example/o')), + RDF::Node.new('o1') + ), + RDF::URI('http://example/p'), RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "_:s1", @@ -914,14 +928,16 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "subject-bil": { + 'subject-bil': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1')), + RDF::Literal('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": "_:s1", @@ -930,14 +946,16 @@ "http://example/p": [{"@id": "http://example/o"}] }]) }, - "object-iii": { + 'object-iii': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1'))), + RDF::URI('http://example/o1') + ) + ), output: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -948,14 +966,16 @@ }] }]) }, - "object-iib": { + 'object-iib': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1'))), + RDF::Node.new('o1') + ) + ), output: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -966,14 +986,16 @@ }] }]) }, - "object-iil": { + 'object-iil': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1'))), + RDF::Literal('o1') + ) + ), output: %([{ "@id": "http://example/s", "http://example/p": [{ @@ -984,17 +1006,20 @@ }] }]) }, - "recursive-subject": { + 'recursive-subject': { input: RDF::Statement( RDF::Statement( RDF::Statement( RDF::URI('http://example/s2'), RDF::URI('http://example/p2'), - RDF::URI('http://example/o2')), + RDF::URI('http://example/o2') + ), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %([{ "@id": { "@id": { @@ -1005,11 +1030,11 @@ }, "http://example/p": [{"@id": "http://example/o"}] }]) - }, + } }.each do |name, params| it name do - graph = RDF::Graph.new {|g| g << params[:input]} - do_fromRdf(params.merge(input: graph, prefixes: {ex: 'http://example/'})) + graph = RDF::Graph.new { |g| g << params[:input] } + do_fromRdf(params.merge(input: graph, prefixes: { ex: 'http://example/' })) end end end @@ -1029,9 +1054,9 @@ { "@id" => "http://www.w3.org/2001/XMLSchema#boolean" } ] }] - }, + } }.each do |t, params| - it "#{t}" do + it t.to_s do do_fromRdf(params) end end @@ -1053,20 +1078,19 @@ def serialize(ntstr, **options) end def do_fromRdf(params) - begin - input, output = params[:input], params[:output] - output = ::JSON.parse(output) if output.is_a?(String) - jld = nil - if params[:write] - expect{jld = serialize(input, **params)}.to write(params[:write]).to(:error) - else - expect{jld = serialize(input, **params)}.not_to write.to(:error) - end - expect(jld).to produce_jsonld(output, logger) - rescue JSON::LD::JsonLdError => e - fail("#{e.class}: #{e.message}\n" + - "#{logger}\n" + - "Backtrace:\n#{e.backtrace.join("\n")}") + input = params[:input] + output = params[:output] + output = JSON.parse(output) if output.is_a?(String) + jld = nil + if params[:write] + expect { jld = serialize(input, **params) }.to write(params[:write]).to(:error) + else + expect { jld = serialize(input, **params) }.not_to write.to(:error) end + expect(jld).to produce_jsonld(output, logger) + rescue JSON::LD::JsonLdError => e + raise("#{e.class}: #{e.message}\n" \ + "#{logger}\n" \ + "Backtrace:\n#{e.backtrace.join("\n")}") end end diff --git a/spec/matchers.rb b/spec/matchers.rb index e5e9c35a..76cc71c2 100644 --- a/spec/matchers.rb +++ b/spec/matchers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rspec/matchers' # @see https://rubygems.org/gems/rspec require_relative 'support/extensions' @@ -7,14 +9,26 @@ end failure_message do |actual| - "Expected: #{expected.is_a?(String) ? expected : expected.to_json(JSON_STATE) rescue 'malformed json'}\n" + - "Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" + - "\nDebug:\n#{logger}" + "Expected: #{begin + expected.is_a?(String) ? expected : expected.to_json(JSON_STATE) + rescue StandardError + 'malformed json' + end}\n" \ + "Actual : #{begin + actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) + rescue StandardError + 'malformed json' + end}\n" \ + "\nDebug:\n#{logger}" end failure_message_when_negated do |actual| - "Expected not to produce the following:\n" + - "Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" + - "\nDebug:\n#{logger}" + "Expected not to produce the following:\n" \ + "Actual : #{begin + actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) + rescue StandardError + 'malformed json' + end}\n" \ + "\nDebug:\n#{logger}" end end diff --git a/spec/rdfstar_spec.rb b/spec/rdfstar_spec.rb index cb9ea7af..08811d9e 100644 --- a/spec/rdfstar_spec.rb +++ b/spec/rdfstar_spec.rb @@ -1,25 +1,28 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - %w{ - expand - compact - flatten - fromRdf - toRdf - }.each do |partial| - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STAR_SUITE}#{partial}-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + %w[ + expand + compact + flatten + fromRdf + toRdf + ].each do |partial| + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STAR_SUITE}#{partial}-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/reader_spec.rb b/spec/reader_spec.rb index d2832b05..8c1005a3 100644 --- a/spec/reader_spec.rb +++ b/spec/reader_spec.rb @@ -1,32 +1,33 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/spec/reader' describe JSON::LD::Reader do - let!(:doap) {File.expand_path("../../etc/doap.jsonld", __FILE__)} - let!(:doap_nt) {File.expand_path("../../etc/doap.nt", __FILE__)} - let!(:doap_count) {File.open(doap_nt).each_line.to_a.length} - let(:logger) {RDF::Spec.logger} + let!(:doap) { File.expand_path('../etc/doap.jsonld', __dir__) } + let!(:doap_nt) { File.expand_path('../etc/doap.nt', __dir__) } + let!(:doap_count) { File.open(doap_nt).each_line.to_a.length } + let(:logger) { RDF::Spec.logger } - after(:each) {|example| puts logger.to_s if example.exception} + after { |example| puts logger if example.exception } it_behaves_like 'an RDF::Reader' do - let(:reader_input) {File.read(doap)} - let(:reader) {JSON::LD::Reader.new(reader_input)} - let(:reader_count) {doap_count} + let(:reader_input) { File.read(doap) } + let(:reader) { JSON::LD::Reader.new(reader_input) } + let(:reader_count) { doap_count } end describe ".for" do - formats = [ + [ :jsonld, "etc/doap.jsonld", - {file_name: 'etc/doap.jsonld'}, - {file_extension: 'jsonld'}, - {content_type: 'application/ld+json'}, - {content_type: 'application/x-ld+json'}, + { file_name: 'etc/doap.jsonld' }, + { file_extension: 'jsonld' }, + { content_type: 'application/ld+json' }, + { content_type: 'application/x-ld+json' } ].each do |arg| it "discovers with #{arg.inspect}" do - expect(RDF::Reader.for(arg)).to eq JSON::LD::Reader + expect(RDF::Reader.for(arg)).to eq described_class end end end @@ -41,14 +42,14 @@ context :interface do { - plain: %q({ + plain: '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "_:bnode1", "@type": "foaf:Person", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" - }), - leading_comment: %q( + }', + leading_comment: ' // A comment before content { "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, @@ -56,8 +57,8 @@ "@type": "foaf:Person", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" - }), - script: %q(), - script_comments: %q(', + script_comments: '), + ' }.each do |variant, src| context variant do - subject {src} + subject { src } describe "#initialize" do it "yields reader given string" do @@ -127,7 +128,8 @@ describe "Base IRI resolution" do # From https://gist.github.com/RubenVerborgh/39f0e8d63e33e435371a - let(:json) {%q{[ + let(:json) do + '[ { "@context": {"@base": "http://a/bb/ccc/d;p?q", "urn:ex:p": {"@type": "@id"}}, "@graph": [ @@ -519,8 +521,10 @@ {"@id": "urn:ex:s306", "urn:ex:p": "../xyz"} ] } - ]}} - let(:nt) {%q{ + ]' + end + let(:nt) do + ' # RFC3986 normal examples . @@ -873,10 +877,12 @@ . . . - }} + ' + end + it "produces equivalent triples" do nt_str = RDF::NTriples::Reader.new(nt).dump(:ntriples) - json_str = JSON::LD::Reader.new(json).dump(:ntriples) + json_str = described_class.new(json).dump(:ntriples) expect(json_str).to eql(nt_str) end end diff --git a/spec/resource_spec.rb b/spec/resource_spec.rb index 5e36bcb4..84e04d21 100644 --- a/spec/resource_spec.rb +++ b/spec/resource_spec.rb @@ -1,32 +1,39 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::Resource do - subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"})} + subject { JSON::LD::Resource.new({ '@id' => '_:foo', "http://schema.org/name" => "foo" }) } + describe "#initialize" do - specify {expect(subject).not_to be_nil} - specify {expect(subject).to be_a(JSON::LD::Resource)} - specify {expect(subject).not_to be_clean} - specify {expect(subject).to be_anonymous} - specify {expect(subject).to be_dirty} - specify {expect(subject).to be_new} - specify {expect(subject).not_to be_resolved} - specify {expect(subject).not_to be_stub} + specify { expect(subject).not_to be_nil } + specify { expect(subject).to be_a(described_class) } + specify { expect(subject).not_to be_clean } + specify { expect(subject).to be_anonymous } + specify { expect(subject).to be_dirty } + specify { expect(subject).to be_new } + specify { expect(subject).not_to be_resolved } + specify { expect(subject).not_to be_stub } + context "schema:name property" do - specify {expect(subject.property("http://schema.org/name")).to eq "foo"} + specify { expect(subject.property("http://schema.org/name")).to eq "foo" } end describe "compacted with context" do - subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"}, compact: true, context: {"@vocab" => "http://schema.org/"})} - specify {expect(subject).not_to be_nil} - specify {expect(subject).to be_a(JSON::LD::Resource)} - specify {expect(subject).not_to be_clean} - specify {expect(subject).to be_anonymous} - specify {expect(subject).to be_dirty} - specify {expect(subject).to be_new} - specify {expect(subject).not_to be_resolved} - specify {expect(subject).not_to be_stub} - its(:name) {should eq "foo"} + subject do + described_class.new({ '@id' => '_:foo', "http://schema.org/name" => "foo" }, compact: true, + context: { "@vocab" => "http://schema.org/" }) + end + + specify { expect(subject).not_to be_nil } + specify { expect(subject).to be_a(described_class) } + specify { expect(subject).not_to be_clean } + specify { expect(subject).to be_anonymous } + specify { expect(subject).to be_dirty } + specify { expect(subject).to be_new } + specify { expect(subject).not_to be_resolved } + specify { expect(subject).not_to be_stub } + its(:name) { is_expected.to eq "foo" } end end @@ -39,8 +46,8 @@ end describe "#hash" do - specify {expect(subject.hash).to be_a(Integer)} - + specify { expect(subject.hash).to be_a(Integer) } + it "returns the hash of the attributes" do expect(subject.hash).to eq subject.deresolve.hash end @@ -51,17 +58,18 @@ expect(subject.to_json).to be_a(String) expect(JSON.parse(subject.to_json)).to be_a(Hash) end + it "has same ID" do expect(JSON.parse(subject.to_json)['@id']).to eq subject.id end end describe "#each" do - specify {expect {|b| subject.each(&b)}.to yield_with_args(subject.statements.first)} + specify { expect { |b| subject.each(&b) }.to yield_with_args(subject.statements.first) } end describe RDF::Enumerable do - specify {expect(subject).to be_enumerable} + specify { expect(subject).to be_enumerable } it "initializes a graph" do g = RDF::Graph.new << subject @@ -71,6 +79,6 @@ end describe "#save" do - specify {expect {subject.save}.to raise_error(NotImplementedError)} + specify { expect { subject.save }.to raise_error(NotImplementedError) } end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 541b2ff5..b81e71ba 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,7 @@ -$:.unshift(File.join("../../lib", __FILE__)) -$:.unshift File.dirname(__FILE__) +# frozen_string_literal: true + +$LOAD_PATH.unshift(File.join("../../lib", __FILE__)) +$LOAD_PATH.unshift File.dirname(__FILE__) require "bundler/setup" require 'rspec' @@ -17,15 +19,15 @@ require 'simplecov' require 'simplecov-lcov' SimpleCov::Formatter::LcovFormatter.config do |config| - #Coveralls is coverage by default/lcov. Send info results + # 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, - SimpleCov::Formatter::LcovFormatter - ]) + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::LcovFormatter + ]) SimpleCov.start do add_filter "/spec/" end @@ -50,7 +52,7 @@ Dir.mkdir(URI_CACHE) unless File.directory?(URI_CACHE) # Cache client requests -::RSpec.configure do |c| +RSpec.configure do |c| c.filter_run focus: true c.run_all_when_everything_filtered = true c.include(RDF::Spec::Matchers) @@ -67,9 +69,9 @@ def detect_format(stream) string = stream.to_s end case string - when / v.to_s)} + if (bijection = ds_actual.bijection_to(ds_expected)) + bijection = bijection.inject({}) { |memo, (k, v)| memo.merge(k.to_s => v.to_s) } # Recursively replace blank nodes in actual with the bijection replace_nodes(actual, bijection) @@ -92,7 +94,7 @@ def remap_bnodes(actual, expected) def replace_nodes(object, bijection) case object when Array - object.map {|o| replace_nodes(o, bijection)} + object.map { |o| replace_nodes(o, bijection) } when Hash object.inject({}) do |memo, (k, v)| memo.merge(bijection.fetch(k, k) => replace_nodes(v, bijection)) @@ -104,7 +106,6 @@ def replace_nodes(object, bijection) end end - LIBRARY_INPUT = JSON.parse(%([ { "@id": "http://example.org/library", diff --git a/spec/streaming_reader_spec.rb b/spec/streaming_reader_spec.rb index 59e92b9c..c3689a0b 100644 --- a/spec/streaming_reader_spec.rb +++ b/spec/streaming_reader_spec.rb @@ -1,39 +1,40 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/spec/reader' -describe JSON::LD::Reader do - let!(:doap) {File.expand_path("../../etc/doap.jsonld", __FILE__)} - let!(:doap_nt) {File.expand_path("../../etc/doap.nt", __FILE__)} - let!(:doap_count) {File.open(doap_nt).each_line.to_a.length} - let(:logger) {RDF::Spec.logger} +describe JSON::LD::StreamingReader do + let!(:doap) { File.expand_path('../etc/doap.jsonld', __dir__) } + let!(:doap_nt) { File.expand_path('../etc/doap.nt', __dir__) } + let!(:doap_count) { File.open(doap_nt).each_line.to_a.length } + let(:logger) { RDF::Spec.logger } - after(:each) {|example| puts logger.to_s if example.exception} + after { |example| puts logger if example.exception } it_behaves_like 'an RDF::Reader' do - let(:reader_input) {File.read(doap)} - let(:reader) {JSON::LD::Reader.new(reader_input, stream: true)} - let(:reader_count) {doap_count} + let(:reader_input) { File.read(doap) } + let(:reader) { JSON::LD::Reader.new(reader_input, stream: true) } + let(:reader_count) { doap_count } end context "when validating", pending: ("JRuby support for jsonlint" if RUBY_ENGINE == "jruby") do it "detects invalid JSON" do expect do |b| - described_class.new(StringIO.new(%({"a": "b", "a": "c"})), validate: true, logger: false).each_statement(&b) + JSON::LD::Reader.new(StringIO.new(%({"a": "b", "a": "c"})), validate: true, logger: false).each_statement(&b) end.to raise_error(RDF::ReaderError) end end context :interface do { - plain: %q({ + plain: '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@type": "foaf:Person", "@id": "_:bnode1", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" - }), - leading_comment: %q( + }', + leading_comment: ' // A comment before content { "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, @@ -41,8 +42,8 @@ "@id": "_:bnode1", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" - }), - script: %q(), - script_comments: %q(', + script_comments: '), + ' }.each do |variant, src| context variant do - subject {src} + subject { src } describe "#initialize" do it "yields reader given string" do @@ -112,7 +113,7 @@ context "Selected toRdf tests" do { - "e004": { + e004: { input: %({ "@context": { "mylist1": {"@id": "http://example.com/mylist1", "@container": "@list"} @@ -128,7 +129,7 @@ . ) }, - "e015": { + e015: { input: %({ "@context": { "myset2": {"@id": "http://example.com/myset2", "@container": "@set" } @@ -139,7 +140,7 @@ expect: %( ) }, - "in06": { + in06: { input: %({ "@context": { "@version": 1.1, @@ -175,60 +176,71 @@ end end - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STREAM_SUITE}stream-toRdf-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do - pending "Generalized RDF" if t.options[:produceGeneralizedRdf] - pending "@nest defining @id" if %w(#tin06).include?(t.property('@id')) - pending "double @reverse" if %w(#te043).include?(t.property('@id')) - pending "graph map containing named graph" if %w(#te084 #te087 #te098 #te101 #te105 #te106).include?(t.property('@id')) - pending "named graphs" if %w(#t0029 #te021).include?(t.property('@id')) - - if %w(#t0118).include?(t.property('@id')) - expect {t.run self}.to write(/Statement .* is invalid/).to(:error) - elsif %w(#twf07).include?(t.property('@id')) - expect {t.run self}.to write(/skipping graph statement within invalid graph name/).to(:error) - elsif %w(#te075).include?(t.property('@id')) - expect {t.run self}.to write(/is invalid/).to(:error) - elsif %w(#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120).include?(t.property('@id')) - expect {t.run self}.to write("beginning with '@' are reserved for future use").to(:error) - elsif %w(#te068).include?(t.property('@id')) - expect {t.run self}.to write("[DEPRECATION]").to(:error) - elsif %w(#twf05).include?(t.property('@id')) - expect {t.run self}.to write("@language must be valid BCP47").to(:error) - else - expect {t.run self}.not_to write.to(:error) + unless ENV['CI'] + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STREAM_SUITE}stream-toRdf-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do + pending "Generalized RDF" if t.options[:produceGeneralizedRdf] + pending "@nest defining @id" if %w[#tin06].include?(t.property('@id')) + pending "double @reverse" if %w[#te043].include?(t.property('@id')) + pending "graph map containing named graph" if %w[#te084 #te087 #te098 #te101 #te105 + #te106].include?(t.property('@id')) + pending "named graphs" if %w[#t0029 #te021].include?(t.property('@id')) + + if %w[#t0118].include?(t.property('@id')) + expect { t.run self }.to write(/Statement .* is invalid/).to(:error) + elsif %w[#twf07].include?(t.property('@id')) + expect { t.run self }.to write(/skipping graph statement within invalid graph name/).to(:error) + elsif %w[#te075].include?(t.property('@id')) + expect { t.run self }.to write(/is invalid/).to(:error) + elsif %w[#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120].include?(t.property('@id')) + expect { t.run self }.to write("beginning with '@' are reserved for future use").to(:error) + elsif %w[#te068].include?(t.property('@id')) + expect { t.run self }.to write("[DEPRECATION]").to(:error) + elsif %w[#twf05].include?(t.property('@id')) + expect { t.run self }.to write("@language must be valid BCP47").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end end end end - end unless ENV['CI'] + end def run_to_rdf(params) input = params[:input] logger.info("input: #{input}") output = RDF::Repository.new if params[:expect] - RDF::NQuads::Reader.new(params[:expect], validate: false) {|r| output << r} + RDF::NQuads::Reader.new(params[:expect], validate: false) { |r| output << r } logger.info("expect (quads): #{output.dump(:nquads, validate: false)}") else logger.info("expect: #{Regexp.new params[:exception]}") end - + graph = params[:graph] || RDF::Repository.new pending params.fetch(:pending, "test implementation") if !input || params[:pending] if params[:exception] expect do |b| JSON::LD::Reader.new(input, stream: true, validate: true, logger: false, **params).each_statement(&b) - end.to raise_error {|er| expect(er.message).to include params[:exception]} + end.to raise_error { |er| expect(er.message).to include params[:exception] } else if params[:write] - expect{JSON::LD::Reader.new(input, stream: true, logger: logger, **params) {|st| graph << st}}.to write(params[:write]).to(:error) + expect do + JSON::LD::Reader.new(input, stream: true, logger: logger, **params) do |st| + graph << st + end + end.to write(params[:write]).to(:error) else - expect{JSON::LD::Reader.new(input, stream: true, logger: logger, **params) {|st| graph << st}}.not_to write.to(:error) + expect do + JSON::LD::Reader.new(input, stream: true, logger: logger, **params) do |st| + graph << st + end + end.not_to write.to(:error) end logger.info("results (quads): #{graph.dump(:nquads, validate: false)}") expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input) diff --git a/spec/streaming_writer_spec.rb b/spec/streaming_writer_spec.rb index a4ec0771..ac4ac21f 100644 --- a/spec/streaming_writer_spec.rb +++ b/spec/streaming_writer_spec.rb @@ -1,25 +1,24 @@ -# coding: utf-8 require_relative 'spec_helper' require 'rdf/spec/writer' require 'json/ld/streaming_writer' describe JSON::LD::StreamingWriter do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } - after(:each) {|example| puts logger.to_s if example.exception} + after { |example| puts logger if example.exception } it_behaves_like 'an RDF::Writer' do - let(:writer) {JSON::LD::Writer.new(StringIO.new(""), stream: true)} + let(:writer) { JSON::LD::Writer.new(StringIO.new(""), stream: true) } end context "simple tests" do - it "should use full URIs without base" do + it "uses full URIs without base" do input = %( .) obj = serialize(input) expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse(input), logger: logger) expect(obj).to produce_jsonld([{ - '@id' => "http://a/b", - "http://a/c" => [{"@id" => "http://a/d"}] + '@id' => "http://a/b", + "http://a/c" => [{ "@id" => "http://a/d" }] }], logger) end @@ -32,98 +31,101 @@ ) obj = serialize(input) expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse(input), logger: logger) - expect(obj).to eql JSON.parse(%{[{ + expect(obj).to eql JSON.parse(%([{ "@id": "https://senet.org/gm", "@type": ["http://vocab.org/frbr/core#Work"], "http://purl.org/dc/terms/title": [{"@value": "Rhythm Paradise", "@language": "en"}], "https://senet.org/ns#unofficialTitle": [{"@value": "Rhythm Tengoku", "@language": "en"}], "https://senet.org/ns#urlkey": [{"@value": "rhythm-tengoku"}] - }]}) + }])) end it "serializes multiple subjects" do - input = %q( + input = ' @prefix : . @prefix dc: . a :TestCase . a :TestCase . - ) + ' obj = serialize(input) expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse(input), logger: logger) - expect(obj).to contain_exactly(*JSON.parse(%{[ + expect(obj).to match_array(JSON.parse(%([ {"@id": "http://example.com/test-cases/0001", "@type": ["http://www.w3.org/2006/03/test-description#TestCase"]}, {"@id": "http://example.com/test-cases/0002", "@type": ["http://www.w3.org/2006/03/test-description#TestCase"]} - ]})) + ]))) end end context "Named Graphs" do { "default" => [ - %q({ .}), - %q([{"@id": "a", "b": [{"@id": "c"}]}]) + '{ .}', + '[{"@id": "a", "b": [{"@id": "c"}]}]' ], "named" => [ - %q( { .}), - %q([{"@id" : "C", "@graph" : [{"@id": "a", "b": [{"@id": "c"}]}]}]) + ' { .}', + '[{"@id" : "C", "@graph" : [{"@id": "a", "b": [{"@id": "c"}]}]}]' ], "combo" => [ - %q( + ' . { .} - ), - %q([ + ', + '[ {"@id": "a", "b": [{"@id": "c"}]}, {"@id": "C", "@graph": [{"@id": "A", "b": [{"@id": "c"}]}]} - ]) + ]' ], "combo with duplicated statement" => [ - %q( + ' . { .} - ), - %q([ + ', + '[ {"@id": "a", "b": [{"@id": "c"}]}, {"@id": "C", "@graph": [{"@id": "a", "b": [{"@id": "c"}]}]} - ]) - ], + ]' + ] }.each_pair do |title, (input, matches)| context title do - subject {serialize(input)} + subject { serialize(input) } + it "matches expected json" do - expect(subject).to contain_exactly(*JSON.parse(matches)) + expect(subject).to match_array(JSON.parse(matches)) end end end end + unless ENV['CI'] + context "Writes fromRdf tests to isomorphic graph" do + require 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") + [nil, {}].each do |ctx| + context "with context #{ctx.inspect}" do + describe m.name do + m.entries.each do |t| + next unless t.positiveTest? && !t.property('input').include?('0016') - context "Writes fromRdf tests to isomorphic graph" do - require 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") - [nil, {}].each do |ctx| - context "with context #{ctx.inspect}" do - describe m.name do - m.entries.each do |t| - next unless t.positiveTest? && !t.property('input').include?('0016') - t.logger = RDF::Spec.logger - t.logger.info "test: #{t.inspect}" - t.logger.info "source: #{t.input}" - specify "#{t.property('@id')}: #{t.name}" do - repo = RDF::Repository.load(t.input_loc, format: :nquads) - jsonld = JSON::LD::Writer.buffer(stream: true, context: ctx, logger: t.logger, **t.options) do |writer| - writer << repo - end - t.logger.info "Generated: #{jsonld}" + t.logger = RDF::Spec.logger + t.logger.info "test: #{t.inspect}" + t.logger.info "source: #{t.input}" + specify "#{t.property('@id')}: #{t.name}" do + repo = RDF::Repository.load(t.input_loc, format: :nquads) + jsonld = JSON::LD::Writer.buffer(stream: true, context: ctx, logger: t.logger, **t.options) do |writer| + writer << repo + end + t.logger.info "Generated: #{jsonld}" - # And then, re-generate jsonld as RDF - expect(parse(jsonld, format: :jsonld, **t.options)).to be_equivalent_graph(repo, t) + # And then, re-generate jsonld as RDF + expect(parse(jsonld, format: :jsonld, **t.options)).to be_equivalent_graph(repo, t) + end end end end end end - end unless ENV['CI'] + end def parse(input, format: :trig, **options) reader = RDF::Reader.for(format) @@ -139,7 +141,7 @@ def serialize(ntstr, **options) writer << g end puts result if $verbose - + JSON.parse(result) end end diff --git a/spec/suite_compact_spec.rb b/spec/suite_compact_spec.rb index 9982f21c..cc3ff9bc 100644 --- a/spec/suite_compact_spec.rb +++ b/spec/suite_compact_spec.rb @@ -1,22 +1,23 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}compact-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect{t.run self}.not_to write.to(:error) - end +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}compact-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + expect { t.run self }.not_to write.to(:error) + end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_expand_spec.rb b/spec/suite_expand_spec.rb index 8d26624e..61c832fd 100644 --- a/spec/suite_expand_spec.rb +++ b/spec/suite_expand_spec.rb @@ -1,36 +1,37 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}expand-manifest.jsonld") - describe m.name do - m.entries.each do |t| - # MultiJson use OJ, by default, which doesn't handle native numbers the same as the JSON gem. - t.options[:adapter] = :json_gem if %w(#tjs12).include?(t.property('@id')) - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - if %w(#t0068).include?(t.property('@id')) - expect{t.run self}.to write("[DEPRECATION]").to(:error) - elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120).include?(t.property('@id')) - expect{t.run self}.to write("beginning with '@' are reserved for future use").to(:error) - else - expect {t.run self}.not_to write.to(:error) +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}expand-manifest.jsonld") + describe m.name do + m.entries.each do |t| + # MultiJson use OJ, by default, which doesn't handle native numbers the same as the JSON gem. + t.options[:adapter] = :json_gem if %w[#tjs12].include?(t.property('@id')) + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + if %w[#t0068].include?(t.property('@id')) + expect { t.run self }.to write("[DEPRECATION]").to(:error) + elsif %w[#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120].include?(t.property('@id')) + expect { t.run self }.to write("beginning with '@' are reserved for future use").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end - end - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - if %w(#t0068).include?(t.property('@id')) - expect{t.run self}.to write("[DEPRECATION]").to(:error) - elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120).include?(t.property('@id')) - expect{t.run self}.to write("beginning with '@' are reserved for future use").to(:error) - else - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + if %w[#t0068].include?(t.property('@id')) + expect { t.run self }.to write("[DEPRECATION]").to(:error) + elsif %w[#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120].include?(t.property('@id')) + expect { t.run self }.to write("beginning with '@' are reserved for future use").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_flatten_spec.rb b/spec/suite_flatten_spec.rb index f2ed27f6..5c34d401 100644 --- a/spec/suite_flatten_spec.rb +++ b/spec/suite_flatten_spec.rb @@ -1,34 +1,36 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}flatten-manifest.jsonld") - describe m.name do - m.entries.each do |t| - t.options[:remap_bnodes] = %w(#t0045).include?(t.property('@id')) +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}flatten-manifest.jsonld") + describe m.name do + m.entries.each do |t| + t.options[:remap_bnodes] = %w[#t0045].include?(t.property('@id')) - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - if %w(#t0005).include?(t.property('@id')) - expect{t.run self}.to write("Terms beginning with '@' are reserved for future use").to(:error) - else - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + if %w[#t0005].include?(t.property('@id')) + expect { t.run self }.to write("Terms beginning with '@' are reserved for future use").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end - end - # Skip ordered tests when remapping bnodes - next if t.options[:remap_bnodes] - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - if %w(#t0005).include?(t.property('@id')) - expect{t.run self}.to write("Terms beginning with '@' are reserved for future use").to(:error) - else - expect {t.run self}.not_to write.to(:error) + # Skip ordered tests when remapping bnodes + next if t.options[:remap_bnodes] + + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + if %w[#t0005].include?(t.property('@id')) + expect { t.run self }.to write("Terms beginning with '@' are reserved for future use").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_frame_spec.rb b/spec/suite_frame_spec.rb index 79c314ce..007851f9 100644 --- a/spec/suite_frame_spec.rb +++ b/spec/suite_frame_spec.rb @@ -1,29 +1,29 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::FRAME_SUITE}frame-manifest.jsonld") - describe m.name do - m.entries.each do |t| - t.options[:remap_bnodes] = %w(#t0021 #tp021).include?(t.property('@id')) +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::FRAME_SUITE}frame-manifest.jsonld") + describe m.name do + m.entries.each do |t| + t.options[:remap_bnodes] = %w[#t0021 #tp021].include?(t.property('@id')) - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) - end + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end + + # Skip ordered tests when remapping bnodes + next if t.options[:remap_bnodes] - # Skip ordered tests when remapping bnodes - next if t.options[:remap_bnodes] - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - if %w(#tp021).include?(t.property('@id')) - pending("changes due to blank node reordering") + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + pending("changes due to blank node reordering") if %w[#tp021].include?(t.property('@id')) + expect { t.run self }.not_to write.to(:error) end - expect {t.run self}.not_to write.to(:error) end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_from_rdf_spec.rb b/spec/suite_from_rdf_spec.rb index 90324d49..1dec141d 100644 --- a/spec/suite_from_rdf_spec.rb +++ b/spec/suite_from_rdf_spec.rb @@ -1,22 +1,23 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) - end +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + expect { t.run self }.not_to write.to(:error) + end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_helper.rb b/spec/suite_helper.rb index 51b83141..35fb8717 100644 --- a/spec/suite_helper.rb +++ b/spec/suite_helper.rb @@ -4,15 +4,16 @@ module RDF::Util module File LOCAL_PATHS = { - "https://w3c.github.io/json-ld-api/tests/" => ::File.expand_path("../json-ld-api/tests", __FILE__) + '/', - "https://w3c.github.io/json-ld-framing/tests/" => ::File.expand_path("../json-ld-framing/tests", __FILE__) + '/', - "https://w3c.github.io/json-ld-streaming/tests/" => ::File.expand_path("../json-ld-streaming/tests", __FILE__) + '/', - "https://json-ld.github.io/json-ld-star/tests/" => ::File.expand_path("../json-ld-star/tests", __FILE__) + '/', + "https://w3c.github.io/json-ld-api/tests/" => ::File.expand_path('json-ld-api/tests', __dir__) + '/', + "https://w3c.github.io/json-ld-framing/tests/" => ::File.expand_path('json-ld-framing/tests', __dir__) + '/', + "https://w3c.github.io/json-ld-streaming/tests/" => ::File.expand_path('json-ld-streaming/tests', + __dir__) + '/', + "https://json-ld.github.io/json-ld-star/tests/" => ::File.expand_path('json-ld-star/tests', __dir__) + '/', "file:" => "" } class << self - alias_method :original_open_file, :open_file + alias original_open_file open_file end ## @@ -27,7 +28,8 @@ class << self def self.open_file(filename_or_url, **options, &block) LOCAL_PATHS.each do |r, l| next unless Dir.exist?(l) && filename_or_url.start_with?(r) - #puts "attempt to open #{filename_or_url} locally" + + # puts "attempt to open #{filename_or_url} locally" url_no_frag_or_query = RDF::URI(filename_or_url).dup url_no_frag_or_query.query = nil url_no_frag_or_query.fragment = nil @@ -39,12 +41,12 @@ def self.open_file(filename_or_url, **options, &block) end document_options = { - base_uri: RDF::URI(filename_or_url), - charset: Encoding::UTF_8, - code: 200, - headers: options.fetch(:headers, {}) + base_uri: RDF::URI(filename_or_url), + charset: Encoding::UTF_8, + code: 200, + headers: options.fetch(:headers, {}) } - #puts "use #{filename_or_url} locally" + # puts "use #{filename_or_url} locally" document_options[:headers][:content_type] = case localpath when /\.ttl$/ then 'text/turtle' when /\.nq$/ then 'application/n-quads' @@ -61,11 +63,9 @@ def self.open_file(filename_or_url, **options, &block) remote_document = RDF::Util::File::RemoteDocument.new(response.read, **document_options) response.close - if block_given? - return yield remote_document - else - return remote_document - end + return yield remote_document if block + + return remote_document end original_open_file(filename_or_url, **options, &block) @@ -87,9 +87,9 @@ def self.open(file) RDF::Util::File.open_file(file) do |remote| json = JSON.parse(remote.read) if block_given? - yield self.from_jsonld(json, manifest_url: RDF::URI(file)) + yield from_jsonld(json, manifest_url: RDF::URI(file)) else - self.from_jsonld(json, manifest_url: RDF::URI(file)) + from_jsonld(json, manifest_url: RDF::URI(file)) end end end @@ -101,7 +101,7 @@ def initialize(json, manifest_url:) # @param [Hash] json framed JSON-LD # @return [Array] - def self.from_jsonld(json, manifest_url: ) + def self.from_jsonld(json, manifest_url:) Manifest.new(json, manifest_url: manifest_url) end @@ -114,8 +114,7 @@ def entries end class Entry < JSON::LD::Resource - attr_accessor :logger - attr_accessor :manifest_url + attr_accessor :logger, :manifest_url def initialize(json, manifest_url:) @manifest_url = manifest_url @@ -132,9 +131,9 @@ def options opts = { documentLoader: Fixtures::SuiteTest.method(:documentLoader), validate: true, - lowercaseLanguage: true, + lowercaseLanguage: true } - {'specVersion' => "json-ld-1.1"}.merge(property('option') || {}).each do |k, v| + { 'specVersion' => "json-ld-1.1" }.merge(property('option') || {}).each do |k, v| opts[k.to_sym] = v end if opts[:expandContext] && !RDF::URI(opts[:expandContext]).absolute? @@ -146,13 +145,14 @@ def options end # Alias input, context, expect and frame - %w(input context expect frame).each do |m| + %w[input context expect frame].each do |m| define_method(m.to_sym) do return nil unless property(m) + res = nil - file = self.send("#{m}_loc".to_sym) + file = send("#{m}_loc".to_sym) - dl_opts = {safe: true} + dl_opts = { safe: true } dl_opts[:contentType] = options[:contentType] if m == 'input' && options[:contentType] RDF::Util::File.open_file(file, **dl_opts) do |remote_doc| res = remote_doc.read @@ -164,20 +164,18 @@ def options file = property(m) # Handle redirection internally - if m == "input" && options[:redirectTo] - file = options[:redirectTo] - end + file = options[:redirectTo] if m == "input" && options[:redirectTo] property(m) && manifest_url.join(file).to_s end define_method("#{m}_json".to_sym) do - JSON.parse(self.send(m)) if property(m) + JSON.parse(send(m)) if property(m) end end def testType - property('@type').reject {|t| t =~ /EvaluationTest|SyntaxTest/}.first + property('@type').reject { |t| t =~ /EvaluationTest|SyntaxTest/ }.first end def evaluationTest? @@ -191,21 +189,24 @@ def positiveTest? def syntaxTest? property('@type').to_s.include?('Syntax') end - # Execute the test def run(rspec_example = nil) logger = @logger = RDF::Spec.logger logger.info "test: #{inspect}" logger.info "purpose: #{purpose}" - logger.info "source: #{input rescue nil}" + logger.info "source: #{begin + input + rescue StandardError + nil + end}" logger.info "context: #{context}" if context_loc logger.info "options: #{options.inspect}" unless options.empty? logger.info "frame: #{frame}" if frame_loc options = self.options if options[:specVersion] == "json-ld-1.0" - skip "1.0 test" + skip "1.0 test" return end @@ -213,7 +214,13 @@ def run(rspec_example = nil) options[:lowercaseLanguage] = true if options[:ordered] if positiveTest? - logger.info "expected: #{expect rescue nil}" if expect_loc + if expect_loc + logger.info "expected: #{begin + expect + rescue StandardError + nil + end}" + end begin result = case testType when "jld:ExpandTest" @@ -229,7 +236,7 @@ def run(rspec_example = nil) repo = RDF::NQuads::Reader.open(input_loc, rdfstar: options[:rdfstar]) do |reader| reader.each_statement.to_a end.to_a.uniq.extend(RDF::Enumerable) - logger.info "repo: #{repo.dump(self.id == '#t0012' ? :nquads : :trig)}" + logger.info "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}" JSON::LD::API.fromRdf(repo, logger: logger, **options) when "jld:ToRDFTest" repo = RDF::Repository.new @@ -249,20 +256,22 @@ def run(rspec_example = nil) rspec_example.instance_eval do # use the parsed input file as @result for Rack Test application @results = res - get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, ""), "HTTP_LINK" => options.fetch(:httpLink, nil) + get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, ""), + "HTTP_LINK" => options.fetch(:httpLink, nil) expect(last_response.status).to eq 200 expect(last_response.content_type).to eq options.fetch(:contentType, "") JSON.parse(last_response.body) end else - fail("Unknown test type: #{testType}") + raise("Unknown test type: #{testType}") end if evaluationTest? if testType == "jld:ToRDFTest" - expected = RDF::Repository.new << RDF::NQuads::Reader.new(expect, rdfstar: options[:rdfstar], logger: []) - rspec_example.instance_eval { + expected = RDF::Repository.new << RDF::NQuads::Reader.new(expect, rdfstar: options[:rdfstar], + logger: []) + rspec_example.instance_eval do expect(result).to be_equivalent_graph(expected, logger) - } + end else expected = JSON.load(expect) @@ -271,76 +280,75 @@ def run(rspec_example = nil) if options[:ordered] # Compare without transformation - rspec_example.instance_eval { + rspec_example.instance_eval do expect(result).to produce(expected, logger) - } + end else # Without key ordering, reorder result and expected embedded array values and compare # If results are compacted, expand both, reorder and re-compare - rspec_example.instance_eval { + rspec_example.instance_eval do expect(result).to produce_jsonld(expected, logger) - } + end # If results are compacted, expand both, reorder and re-compare if result.to_s.include?('@context') exp_expected = JSON::LD::API.expand(expected, **options) exp_result = JSON::LD::API.expand(result, **options) - rspec_example.instance_eval { + rspec_example.instance_eval do expect(exp_result).to produce_jsonld(exp_expected, logger) - } + end end end end else - rspec_example.instance_eval { - expect(result).to_not be_nil - } + rspec_example.instance_eval do + expect(result).not_to be_nil + end end rescue JSON::LD::JsonLdError => e - fail("Processing error: #{e.message}") + raise("Processing error: #{e.message}") end else logger.info "expected: #{property('expect')}" if property('expect') t = self rspec_example.instance_eval do - if t.evaluationTest? - expect do - case t.testType - when "jld:ExpandTest" - JSON::LD::API.expand(t.input_loc, logger: logger, **options) - when "jld:CompactTest" - JSON::LD::API.compact(t.input_loc, t.context_json['@context'], logger: logger, **options) - when "jld:FlattenTest" - JSON::LD::API.flatten(t.input_loc, t.context_loc, logger: logger, **options) - when "jld:FrameTest" - JSON::LD::API.frame(t.input_loc, t.frame_loc, logger: logger, **options) - when "jld:FromRDFTest" - repo = RDF::Repository.load(t.input_loc, rdfstar: options[:rdfstar]) - logger.info "repo: #{repo.dump(t.id == '#t0012' ? :nquads : :trig)}" - JSON::LD::API.fromRdf(repo, logger: logger, **options) - when "jld:HttpTest" - rspec_example.instance_eval do - # use the parsed input file as @result for Rack Test application - @results = t.input_json - get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, "") - expect(last_response.status).to eq t.property('expect') - expect(last_response.content_type).to eq options.fetch(:contentType, "") - raise "406" if t.property('expect') == 406 - raise "Expected status #{t.property('expectErrorCode')}, not #{last_response.status}" - end - when "jld:ToRDFTest" - if t.manifest_url.to_s.include?('stream') - JSON::LD::Reader.open(t.input_loc, stream: true, logger: logger, **options).each_statement {} - else - JSON::LD::API.toRdf(t.input_loc, rename_bnodes: false, logger: logger, **options) {} - end + raise("No support for NegativeSyntaxTest") unless t.evaluationTest? + + expect do + case t.testType + when "jld:ExpandTest" + JSON::LD::API.expand(t.input_loc, logger: logger, **options) + when "jld:CompactTest" + JSON::LD::API.compact(t.input_loc, t.context_json['@context'], logger: logger, **options) + when "jld:FlattenTest" + JSON::LD::API.flatten(t.input_loc, t.context_loc, logger: logger, **options) + when "jld:FrameTest" + JSON::LD::API.frame(t.input_loc, t.frame_loc, logger: logger, **options) + when "jld:FromRDFTest" + repo = RDF::Repository.load(t.input_loc, rdfstar: options[:rdfstar]) + logger.info "repo: #{repo.dump(t.id == '#t0012' ? :nquads : :trig)}" + JSON::LD::API.fromRdf(repo, logger: logger, **options) + when "jld:HttpTest" + rspec_example.instance_eval do + # use the parsed input file as @result for Rack Test application + @results = t.input_json + get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, "") + expect(last_response.status).to eq t.property('expect') + expect(last_response.content_type).to eq options.fetch(:contentType, "") + raise "406" if t.property('expect') == 406 + + raise "Expected status #{t.property('expectErrorCode')}, not #{last_response.status}" + end + when "jld:ToRDFTest" + if t.manifest_url.to_s.include?('stream') + JSON::LD::Reader.open(t.input_loc, stream: true, logger: logger, **options).each_statement {} else - success("Unknown test type: #{testType}") + JSON::LD::API.toRdf(t.input_loc, rename_bnodes: false, logger: logger, **options) {} end - end.to raise_error(/#{t.property('expectErrorCode')}/) - else - fail("No support for NegativeSyntaxTest") - end + else + success("Unknown test type: #{testType}") + end + end.to raise_error(/#{t.property('expectErrorCode')}/) end end end @@ -365,7 +373,7 @@ def to_quad(thing) v += "@#{thing.language}" if thing.language v when RDF::Statement - thing.to_quad.map {|r| to_quad(r)}.compact.join(" ") + " .\n" + thing.to_quad.map { |r| to_quad(r) }.compact.join(" ") + " .\n" end end @@ -380,8 +388,8 @@ def quoted(string) # @param [String, #to_s] string # @return [String] def escaped(string) - string.to_s.gsub('\\', '\\\\').gsub("\t", '\\t'). - gsub("\n", '\\n').gsub("\r", '\\r').gsub('"', '\\"') + string.to_s.gsub('\\', '\\\\').gsub("\t", '\\t') + .gsub("\n", '\\n').gsub("\r", '\\r').gsub('"', '\\"') end end @@ -399,11 +407,12 @@ def escaped(string) def documentLoader(url, **options, &block) options[:headers] ||= JSON::LD::API::OPEN_OPTS[:headers].dup options[:headers][:link] = Array(options[:httpLink]).join(',') if options[:httpLink] - + url = url.to_s[5..-1] if url.to_s.start_with?("file:") JSON::LD::API.documentLoader(url, **options, &block) rescue JSON::LD::JsonLdError::LoadingDocumentFailed, JSON::LD::JsonLdError::MultipleContextLinkHeaders raise unless options[:safe] + "don't raise error" end module_function :documentLoader diff --git a/spec/suite_html_spec.rb b/spec/suite_html_spec.rb index 0a20bd38..27246613 100644 --- a/spec/suite_html_spec.rb +++ b/spec/suite_html_spec.rb @@ -1,22 +1,23 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}html-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) - end +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}html-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + expect { t.run self }.not_to write.to(:error) + end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_http_spec.rb b/spec/suite_http_spec.rb index f573870c..14a6a04d 100644 --- a/spec/suite_http_spec.rb +++ b/spec/suite_http_spec.rb @@ -1,35 +1,37 @@ -# coding: utf-8 require_relative 'spec_helper' require 'rack/linkeddata' require 'rack/test' begin - describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}http-manifest.jsonld") - describe m.name do - include ::Rack::Test::Methods - before(:all) {JSON::LD::Writer.default_context = "#{Fixtures::SuiteTest::SUITE}http/default-context.jsonld"} - after(:all) {JSON::LD::Writer.default_context = nil} - let(:app) do - JSON::LD::ContentNegotiation.new( - Rack::LinkedData::ContentNegotiation.new( - double("Target Rack Application", :call => [200, {}, @results]), - {} + unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}http-manifest.jsonld") + describe m.name do + include Rack::Test::Methods + before(:all) { JSON::LD::Writer.default_context = "#{Fixtures::SuiteTest::SUITE}http/default-context.jsonld" } + after(:all) { JSON::LD::Writer.default_context = nil } + + let(:app) do + JSON::LD::ContentNegotiation.new( + Rack::LinkedData::ContentNegotiation.new( + double("Target Rack Application", :call => [200, {}, @results]), + {} + ) ) - ) - end + end - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end end end end end - end unless ENV['CI'] + end rescue IOError # Skip this until such a test suite is re-added -end \ No newline at end of file +end diff --git a/spec/suite_remote_doc_spec.rb b/spec/suite_remote_doc_spec.rb index 2341da5d..012a843c 100644 --- a/spec/suite_remote_doc_spec.rb +++ b/spec/suite_remote_doc_spec.rb @@ -1,22 +1,23 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}remote-doc-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = false - expect {t.run self}.not_to write.to(:error) - end +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}remote-doc-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = false + expect { t.run self }.not_to write.to(:error) + end - specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do - t.options[:ordered] = true - expect {t.run self}.not_to write.to(:error) + specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do + t.options[:ordered] = true + expect { t.run self }.not_to write.to(:error) + end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/suite_to_rdf_spec.rb b/spec/suite_to_rdf_spec.rb index 48f664d0..c003cd1c 100644 --- a/spec/suite_to_rdf_spec.rb +++ b/spec/suite_to_rdf_spec.rb @@ -1,30 +1,31 @@ -# coding: utf-8 require_relative 'spec_helper' -describe JSON::LD do - describe "test suite" do - require_relative 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}toRdf-manifest.jsonld") - describe m.name do - m.entries.each do |t| - specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do - pending "Generalized RDF" if t.options[:produceGeneralizedRdf] - pending "RDF-star" if t.property('@id') == '#te122' - if %w(#t0118).include?(t.property('@id')) - expect {t.run self}.to write(/Statement .* is invalid/).to(:error) - elsif %w(#te075).include?(t.property('@id')) - expect {t.run self}.to write(/is invalid/).to(:error) - elsif %w(#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120).include?(t.property('@id')) - expect {t.run self}.to write("beginning with '@' are reserved for future use").to(:error) - elsif %w(#te068).include?(t.property('@id')) - expect {t.run self}.to write("[DEPRECATION]").to(:error) - elsif %w(#twf05).include?(t.property('@id')) - expect {t.run self}.to write("@language must be valid BCP47").to(:error) - else - expect {t.run self}.not_to write.to(:error) +unless ENV['CI'] + describe JSON::LD do + describe "test suite" do + require_relative 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}toRdf-manifest.jsonld") + describe m.name do + m.entries.each do |t| + specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do + pending "Generalized RDF" if t.options[:produceGeneralizedRdf] + pending "RDF-star" if t.property('@id') == '#te122' + if %w[#t0118].include?(t.property('@id')) + expect { t.run self }.to write(/Statement .* is invalid/).to(:error) + elsif %w[#te075].include?(t.property('@id')) + expect { t.run self }.to write(/is invalid/).to(:error) + elsif %w[#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120].include?(t.property('@id')) + expect { t.run self }.to write("beginning with '@' are reserved for future use").to(:error) + elsif %w[#te068].include?(t.property('@id')) + expect { t.run self }.to write("[DEPRECATION]").to(:error) + elsif %w[#twf05].include?(t.property('@id')) + expect { t.run self }.to write("@language must be valid BCP47").to(:error) + else + expect { t.run self }.not_to write.to(:error) + end end end end end end -end unless ENV['CI'] \ No newline at end of file +end diff --git a/spec/support/extensions.rb b/spec/support/extensions.rb index dc352a3d..322ad54e 100644 --- a/spec/support/extensions.rb +++ b/spec/support/extensions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Object def equivalent_jsonld?(other, ordered: false) self == other @@ -7,6 +9,7 @@ def equivalent_jsonld?(other, ordered: false) class Hash def equivalent_jsonld?(other, ordered: false) return false unless other.is_a?(Hash) && other.length == length + all? do |key, value| # List values are still ordered if key == '@language' && value.is_a?(String) @@ -18,11 +21,8 @@ def equivalent_jsonld?(other, ordered: false) end def diff(other) - self.keys.inject({}) do |memo, key| - unless self[key] == other[key] - memo[key] = [self[key], other[key]] - end - memo + keys.each_with_object({}) do |key, memo| + memo[key] = [self[key], other[key]] unless self[key] == other[key] end end end @@ -30,14 +30,15 @@ def diff(other) class Array def equivalent_jsonld?(other, ordered: false) return false unless other.is_a?(Array) && other.length == length + if ordered b = other.dup # All elements must match in order - all? {|av| av.equivalent_jsonld?(b.shift)} + all? { |av| av.equivalent_jsonld?(b.shift) } else # Look for any element which matches all? do |av| - other.any? {|bv| av.equivalent_jsonld?(bv)} + other.any? { |bv| av.equivalent_jsonld?(bv) } end end end diff --git a/spec/to_rdf_spec.rb b/spec/to_rdf_spec.rb index e5fe1c0f..c1b48f43 100644 --- a/spec/to_rdf_spec.rb +++ b/spec/to_rdf_spec.rb @@ -1,36 +1,37 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' describe JSON::LD::API do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } - context ".toRdf" do - it "should implement RDF::Enumerable" do - expect(JSON::LD::API.toRdf({})).to be_a(RDF::Enumerable) + describe ".toRdf" do + it "implements RDF::Enumerable" do + expect(described_class.toRdf({})).to be_a(RDF::Enumerable) end context "unnamed nodes" do { "no @id" => [ - %q({ + '{ "http://example.com/foo": "bar" - }), - %q([ "bar"^^xsd:string] .) + }', + '[ "bar"^^xsd:string] .' ], "@id with _:a" => [ - %q({ + '{ "@id": "_:a", "http://example.com/foo": "bar" - }), - %q([ "bar"^^xsd:string] .) + }', + '[ "bar"^^xsd:string] .' ], "@id with _:a and reference" => [ - %q({ + '{ "@id": "_:a", "http://example.com/foo": {"@id": "_:a"} - }), - %q(_:a _:a .) - ], + }', + '_:a _:a .' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -42,19 +43,19 @@ context "nodes with @id" do { "with IRI" => [ - %q({ + '{ "@id": "http://example.com/a", "http://example.com/foo": "bar" - }), - %q( "bar" .) - ], + }', + ' "bar" .' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) end end - + context "with relative IRIs" do { "base" => [ @@ -77,11 +78,12 @@ "@type": "#{RDF::RDFS.Resource}" }), %( a <#{RDF::RDFS.Resource}> .) - ], + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" - expect(parse(js, base: "http://example.org/")).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) + expect(parse(js, + base: "http://example.org/")).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) end end end @@ -90,22 +92,22 @@ context "typed nodes" do { "one type" => [ - %q({ + '{ "@type": "http://example.com/foo" - }), - %q([ a ] .) + }', + '[ a ] .' ], "two types" => [ - %q({ + '{ "@type": ["http://example.com/foo", "http://example.com/baz"] - }), - %q([ a , ] .) + }', + '[ a , ] .' ], "blank node type" => [ - %q({ + '{ "@type": "_:foo" - }), - %q([ a _:foo ] .) + }', + '[ a _:foo ] .' ] }.each do |title, (js, ttl)| it title do @@ -118,29 +120,29 @@ context "key/value" do { "string" => [ - %q({ + '{ "http://example.com/foo": "bar" - }), - %q([ "bar"^^xsd:string ] .) + }', + '[ "bar"^^xsd:string ] .' ], "strings" => [ - %q({ + '{ "http://example.com/foo": ["bar", "baz"] - }), - %q([ "bar"^^xsd:string, "baz"^^xsd:string ] .) + }', + '[ "bar"^^xsd:string, "baz"^^xsd:string ] .' ], "IRI" => [ - %q({ + '{ "http://example.com/foo": {"@id": "http://example.com/bar"} - }), - %q([ ] .) + }', + '[ ] .' ], "IRIs" => [ - %q({ + '{ "http://example.com/foo": [{"@id": "http://example.com/bar"}, {"@id": "http://example.com/baz"}] - }), - %q([ , ] .) - ], + }', + '[ , ] .' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -153,28 +155,28 @@ { "plain literal" => [ - %q({"@id": "http://greggkellogg.net/foaf#me", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg"}), - %q( "Gregg Kellogg" .) + '{"@id": "http://greggkellogg.net/foaf#me", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg"}', + ' "Gregg Kellogg" .' ], "explicit plain literal" => [ - %q({"http://xmlns.com/foaf/0.1/name": {"@value": "Gregg Kellogg"}}), - %q(_:a "Gregg Kellogg"^^xsd:string .) + '{"http://xmlns.com/foaf/0.1/name": {"@value": "Gregg Kellogg"}}', + '_:a "Gregg Kellogg"^^xsd:string .' ], "language tagged literal" => [ - %q({"http://www.w3.org/2000/01/rdf-schema#label": {"@value": "A plain literal with a lang tag.", "@language": "en-us"}}), - %q(_:a "A plain literal with a lang tag."@en-us .) + '{"http://www.w3.org/2000/01/rdf-schema#label": {"@value": "A plain literal with a lang tag.", "@language": "en-us"}}', + '_:a "A plain literal with a lang tag."@en-us .' ], "I18N literal with language" => [ - %q([{ + '[{ "@id": "http://greggkellogg.net/foaf#me", "http://xmlns.com/foaf/0.1/knows": {"@id": "http://www.ivan-herman.net/foaf#me"} },{ "@id": "http://www.ivan-herman.net/foaf#me", "http://xmlns.com/foaf/0.1/name": {"@value": "Herman Iván", "@language": "hu"} - }]), + }]', %q( . "Herman Iv\u00E1n"@hu . @@ -182,14 +184,14 @@ ], "explicit datatyped literal" => [ - %q({ + '{ "@id": "http://greggkellogg.net/foaf#me", "http://purl.org/dc/terms/created": {"@value": "1957-02-27", "@type": "http://www.w3.org/2001/XMLSchema#date"} - }), - %q( + }', + ' "1957-02-27"^^ . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -199,7 +201,7 @@ context "with @type: @json" do { - "true": { + true => { input: %({ "@context": { "@version": 1.1, @@ -207,13 +209,13 @@ }, "e": true }), - output:%( + output: %( @prefix ex: . @prefix rdf: . [ex:bool "true"^^rdf:JSON] . ) }, - "false": { + false => { input: %({ "@context": { "@version": 1.1, @@ -227,7 +229,7 @@ [ex:bool "false"^^rdf:JSON] . ) }, - "double": { + double: { input: %({ "@context": { "@version": 1.1, @@ -241,7 +243,7 @@ [ex:double "1.23"^^rdf:JSON] . ) }, - "double-zero": { + 'double-zero': { input: %({ "@context": { "@version": 1.1, @@ -255,7 +257,7 @@ [ex:double "0"^^rdf:JSON] . ) }, - "integer": { + integer: { input: %({ "@context": { "@version": 1.1, @@ -269,7 +271,7 @@ [ex:integer "123"^^rdf:JSON] . ) }, - "string": { + string: { input: %({ "@context": { "@version": 1.1, @@ -283,7 +285,7 @@ [ex:string "\\"string\\""^^rdf:JSON] . ) }, - "null": { + null: { input: %({ "@context": { "@version": 1.1, @@ -297,7 +299,7 @@ [ex:null "null"^^rdf:JSON] . ) }, - "object": { + object: { input: %({ "@context": { "@version": 1.1, @@ -311,7 +313,7 @@ [ex:object """{"foo":"bar"}"""^^rdf:JSON] . ) }, - "array": { + array: { input: %({ "@context": { "@version": 1.1, @@ -325,7 +327,7 @@ [ex:array """[{"foo":"bar"}]"""^^rdf:JSON] . ) }, - "c14n-arrays": { + 'c14n-arrays': { input: %({ "@context": { "@version": 1.1, @@ -346,7 +348,7 @@ [ex:c14n """[56,{"1":[],"10":null,"d":true}]"""^^rdf:JSON] . ) }, - "c14n-french": { + 'c14n-french': { input: %({ "@context": { "@version": 1.1, @@ -365,7 +367,7 @@ [ex:c14n """{"peach":"This sorting order","péché":"is wrong according to French","pêche":"but canonicalization MUST","sin":"ignore locale"}"""^^rdf:JSON] . ) }, - "c14n-structures": { + 'c14n-structures': { input: %({ "@context": { "@version": 1.1, @@ -386,7 +388,7 @@ [ex:c14n """{"":"empty","1":{" ":56,"f":{"F":5,"f":"hi"}},"10":{},"111":[{"E":"no","e":"yes"}],"A":{},"a":{}}"""^^rdf:JSON] . ) }, - "c14n-unicode": { + 'c14n-unicode': { input: %({ "@context": { "@version": 1.1, @@ -401,7 +403,7 @@ @prefix rdf: . [ex:c14n """{"Unnormalized Unicode":"Å"}"""^^rdf:JSON] . ) - }, + } }.each do |title, params| it title do params[:output] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:output]) @@ -412,7 +414,7 @@ context "with xsd: true" do { - "true": { + true => { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -425,7 +427,7 @@ [ex:e true] . ) }, - "integer": { + integer: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -438,7 +440,7 @@ [ex:e 1] . ) }, - "decimal": { + decimal: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -451,7 +453,7 @@ [ex:e 1.1] . ) }, - "float": { + float: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -465,7 +467,7 @@ [ex:e "1.1e1"^^xsd:float] . ) }, - "double": { + double: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -479,7 +481,7 @@ [ex:e 1.1e1] . ) }, - "date": { + date: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -493,7 +495,7 @@ [ex:e "2022-08-27"^^xsd:date] . ) }, - "time": { + time: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -507,7 +509,7 @@ [ex:e "12:00:00"^^xsd:time] . ) }, - "dateTime": { + dateTime: { input: { "@context" => { "e" => "http://example.org/vocab#e" @@ -521,12 +523,12 @@ [ex:e "2022-08-27T12:00:00"^^xsd:dateTime] . ) }, - "language": { + language: { input: { "@context" => { "e" => "http://example.org/vocab#e" }, - "e" => RDF::Literal.new("language", language: :"en-us") + "e" => RDF::Literal.new("language", language: :'en-us') }, output: %( @prefix ex: . @@ -534,7 +536,7 @@ @prefix xsd: . [ex:e "language"@en-us] . ) - }, + } }.each do |title, params| it title do params[:output] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:output]) @@ -547,12 +549,12 @@ context "prefixes" do { "empty suffix" => [ - %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:": "bar"}), - %q(_:a "bar"^^xsd:string .) + '{"@context": {"prefix": "http://example.com/default#"}, "prefix:": "bar"}', + '_:a "bar"^^xsd:string .' ], "prefix:suffix" => [ - %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:foo": "bar"}), - %q(_:a "bar"^^xsd:string .) + '{"@context": {"prefix": "http://example.com/default#"}, "prefix:foo": "bar"}', + '_:a "bar"^^xsd:string .' ] }.each_pair do |title, (js, ttl)| it title do @@ -565,17 +567,17 @@ context "overriding keywords" do { "'url' for @id, 'a' for @type" => [ - %q({ + '{ "@context": {"url": "@id", "a": "@type", "name": "http://schema.org/name"}, "url": "http://example.com/about#gregg", "a": "http://schema.org/Person", "name": "Gregg Kellogg" - }), - %q( + }', + ' . "Gregg Kellogg"^^xsd:string . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -588,33 +590,33 @@ { "explicit subject" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": { "@id": "http://www.ivan-herman.net/foaf#me", "foaf:name": "Ivan Herman" } - }), - %q( + }', + ' . "Ivan Herman" . - ) + ' ], "implicit subject" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": { "foaf:name": "Manu Sporny" } - }), - %q( + }', + ' _:a . _:a "Manu Sporny"^^xsd:string . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -627,16 +629,16 @@ { "literals" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": ["Manu Sporny", "Ivan Herman"] - }), - %q( + }', + ' "Manu Sporny" . "Ivan Herman" . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -648,74 +650,74 @@ context "lists" do { "Empty" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": {"@list": []} - }), - %q( + }', + ' . - ) + ' ], "single value" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": {"@list": ["Manu Sporny"]} - }), - %q( + }', + ' _:a . _:a "Manu Sporny"^^xsd:string . _:a . - ) + ' ], "single value (with coercion)" => [ - %q({ + '{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "foaf:knows": { "@container": "@list"} }, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": ["Manu Sporny"] - }), - %q( + }', + ' _:a . _:a "Manu Sporny"^^xsd:string . _:a . - ) + ' ], "multiple values" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@id": "http://greggkellogg.net/foaf#me", "foaf:knows": {"@list": ["Manu Sporny", "Dave Longley"]} - }), - %q( + }', + ' _:a . _:a "Manu Sporny"^^xsd:string . _:a _:b . _:b "Dave Longley"^^xsd:string . _:b . - ) + ' ], "@list containing @list" => [ - %q({ + '{ "@id": "http://example/A", "http://example.com/foo": {"@list": [{"@list": ["baz"]}]} - }), - %q( + }', + ' (("baz")) . - ) + ' ], "@list containing empty @list" => [ %({ "@id": "http://example/A", "http://example.com/foo": {"@list": [{"@list": []}]} }), - %q( + ' (()) . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -728,20 +730,20 @@ { "@id coersion" => [ - %q({ + '{ "@context": { "knows": {"@id": "http://xmlns.com/foaf/0.1/knows", "@type": "@id"} }, "@id": "http://greggkellogg.net/foaf#me", "knows": "http://www.ivan-herman.net/foaf#me" - }), - %q( + }', + ' . - ) + ' ], "datatype coersion" => [ - %q({ + '{ "@context": { "dcterms": "http://purl.org/dc/terms/", "xsd": "http://www.w3.org/2001/XMLSchema#", @@ -749,132 +751,132 @@ }, "@id": "http://greggkellogg.net/foaf#me", "created": "1957-02-27" - }), - %q( + }', + ' "1957-02-27"^^ . - ) + ' ], "sub-objects with context" => [ - %q({ + '{ "@context": {"foo": "http://example.com/foo"}, "foo": { "@context": {"foo": "http://example.org/foo"}, "foo": "bar" } - }), - %q( + }', + ' _:a _:b . _:b "bar"^^xsd:string . - ) + ' ], "contexts with a list processed in order" => [ - %q({ + '{ "@context": [ {"foo": "http://example.com/foo"}, {"foo": "http://example.org/foo"} ], "foo": "bar" - }), - %q( + }', + ' _:b "bar"^^xsd:string . - ) + ' ], "term definition resolves term as IRI" => [ - %q({ + '{ "@context": [ {"foo": "http://example.com/foo"}, {"bar": "foo"} ], "bar": "bar" - }), - %q( + }', + ' _:b "bar"^^xsd:string . - ) + ' ], "term definition resolves prefix as IRI" => [ - %q({ + '{ "@context": [ {"foo": "http://example.com/foo#"}, {"bar": "foo:bar"} ], "bar": "bar" - }), - %q( + }', + ' _:b "bar"^^xsd:string . - ) + ' ], "@language" => [ - %q({ + '{ "@context": { "foo": "http://example.com/foo#", "@language": "en" }, "foo:bar": "baz" - }), - %q( + }', + ' _:a "baz"@en . - ) + ' ], "@language with override" => [ - %q({ + '{ "@context": { "foo": "http://example.com/foo#", "@language": "en" }, "foo:bar": {"@value": "baz", "@language": "fr"} - }), - %q( + }', + ' _:a "baz"@fr . - ) + ' ], "@language with plain" => [ - %q({ + '{ "@context": { "foo": "http://example.com/foo#", "@language": "en" }, "foo:bar": {"@value": "baz"} - }), - %q( + }', + ' _:a "baz"^^xsd:string . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" expect(parse(js)).to be_equivalent_graph(ttl, base: "http://example/", logger: logger, inputDocument: js) end end - + context "coercion" do context "term def with @id + @type" do { "dt with term" => [ - %q({ + '{ "@context": [ {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"}, {"foo": {"@id": "term", "@type": "date"}} ], "foo": "bar" - }), - %q( + }', + ' @prefix xsd: . [ "bar"^^xsd:date ] . - ) + ' ], "@id with term" => [ - %q({ + '{ "@context": [ {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id"}} ], "foo": "http://example.org/foo#bar" - }), - %q( + }', + ' _:a . - ) + ' ], "coercion without term definition" => [ - %q({ + '{ "@context": [ { "xsd": "http://www.w3.org/2001/XMLSchema#", @@ -885,13 +887,13 @@ } ], "dc:date": "2011-11-23" - }), - %q( + }', + ' @prefix xsd: . @prefix dc: . [ dc:date "2011-11-23"^^xsd:date] . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -905,29 +907,29 @@ context "term def with @id + @type + @container" do { "dt with term" => [ - %q({ + '{ "@context": [ {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"}, {"foo": {"@id": "term", "@type": "date", "@container": "@list"}} ], "foo": ["bar"] - }), - %q( + }', + ' @prefix xsd: . [ ("bar"^^xsd:date) ] . - ) + ' ], "@id with term" => [ - %q({ + '{ "@context": [ {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id", "@container": "@list"}} ], "foo": ["http://example.org/foo#bar"] - }), - %q( + }', + ' _:a () . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -939,7 +941,7 @@ end context "blank node predicates" do - subject {%q({"@id": "http://example/subj", "_:foo": "bar"})} + subject { '{"@id": "http://example/subj", "_:foo": "bar"}' } it "outputs statements with blank node predicates if :produceGeneralizedRdf is true" do expect do @@ -958,7 +960,7 @@ context "@included" do { - "Basic Included array": { + 'Basic Included array': { input: %({ "@context": { "@version": 1.1, @@ -974,7 +976,7 @@ [ "value2"] . ) }, - "Basic Included object": { + 'Basic Included object': { input: %({ "@context": { "@version": 1.1, @@ -990,7 +992,7 @@ [ "value2"] . ) }, - "Multiple properties mapping to @included are folded together": { + 'Multiple properties mapping to @included are folded together': { input: %({ "@context": { "@version": 1.1, @@ -1006,7 +1008,7 @@ [ "value2"] . ) }, - "Included containing @included": { + 'Included containing @included': { input: %({ "@context": { "@version": 1.1, @@ -1028,7 +1030,7 @@ [ "value3"] . ) }, - "Property value with @included": { + 'Property value with @included': { input: %({ "@context": { "@version": 1.1, @@ -1046,7 +1048,7 @@ [a ] . ) }, - "json.api example": { + 'json.api example': { input: %({ "@context": { "@version": 1.1, @@ -1167,9 +1169,9 @@ ; "dgeb" . ) - }, + } }.each do |title, params| - it(title) {run_to_rdf params} + it(title) { run_to_rdf params } end end @@ -1177,60 +1179,60 @@ { "number syntax (decimal)" => [ - %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3}), - %q(_:a "5.3E0"^^ .) + '{"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3}', + '_:a "5.3E0"^^ .' ], "number syntax (double)" => [ - %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3e0}), - %q(_:a "5.3E0"^^ .) + '{"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3e0}', + '_:a "5.3E0"^^ .' ], "number syntax (integer)" => [ - %q({"@context": { "chem": "http://example/chem#"}, "chem:protons": 12}), - %q(_:a "12"^^ .) + '{"@context": { "chem": "http://example/chem#"}, "chem:protons": 12}', + '_:a "12"^^ .' ], "boolan syntax" => [ - %q({"@context": { "sensor": "http://example/sensor#"}, "sensor:active": true}), - %q(_:a "true"^^ .) + '{"@context": { "sensor": "http://example/sensor#"}, "sensor:active": true}', + '_:a "true"^^ .' ], "Array top element" => [ - %q([ + '[ {"@id": "http://example.com/#me", "@type": "http://xmlns.com/foaf/0.1/Person"}, {"@id": "http://example.com/#you", "@type": "http://xmlns.com/foaf/0.1/Person"} - ]), - %q( + ]', + ' . . - ) + ' ], "@graph with array of objects value" => [ - %q({ + '{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, "@graph": [ {"@id": "http://example.com/#me", "@type": "foaf:Person"}, {"@id": "http://example.com/#you", "@type": "foaf:Person"} ] - }), - %q( + }', + ' . . - ) + ' ], "XMLLiteral" => [ - %q({ + '{ "http://rdfs.org/sioc/ns#content": { "@value": "foo", "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } - }), - %q( + }', + ' [ "foo"^^] . - ) - ], + ' + ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" @@ -1242,13 +1244,13 @@ context "@direction" do context "rdfDirection: null" do { - "no language rtl": [ - %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}), - %q(_:a "no language" .) + 'no language rtl': [ + '{"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}', + '_:a "no language" .' ], - "en-US rtl": [ - %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}), - %q(_:a "en-US"@en-us .) + 'en-US rtl': [ + '{"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}', + '_:a "en-US"@en-us .' ] }.each do |title, (js, ttl)| it title do @@ -1260,49 +1262,51 @@ context "rdfDirection: i18n-datatype" do { - "no language rtl": [ - %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}), - %q(_:a "no language"^^ .) + 'no language rtl': [ + '{"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}', + '_:a "no language"^^ .' ], - "en-US rtl": [ - %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}), - %q(_:a "en-US"^^ .) + 'en-US rtl': [ + '{"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}', + '_:a "en-US"^^ .' ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" - expect(parse(js, rdfDirection: 'i18n-datatype')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) + expect(parse(js, + rdfDirection: 'i18n-datatype')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) end end end context "rdfDirection: compound-literal" do { - "no language rtl": [ - %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}), - %q( + 'no language rtl': [ + '{"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}', + ' @prefix rdf: . _:a [ rdf:value "no language"; rdf:direction "rtl" ] . - ) + ' ], - "en-US rtl": [ - %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}), - %q( + 'en-US rtl': [ + '{"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}', + ' @prefix rdf: . _:a [ rdf:value "en-US"; rdf:language "en-us"; rdf:direction "rtl" ] . - ) + ' ] }.each do |title, (js, ttl)| it title do ttl = "@prefix xsd: . #{ttl}" - expect(parse(js, rdfDirection: 'compound-literal')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) + expect(parse(js, + rdfDirection: 'compound-literal')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js) end end end @@ -1310,7 +1314,7 @@ context "JSON-LD-star" do { - "node with embedded subject without rdfstar option": { + 'node with embedded subject without rdfstar option': { input: %({ "@id": { "@id": "ex:rei", @@ -1319,13 +1323,13 @@ "ex:prop": "value2" }), exception: JSON::LD::JsonLdError::InvalidIdValue - }, + } }.each do |title, params| - it(title) {run_to_rdf params} + it(title) { run_to_rdf params } end { - "node with embedded subject having no @id": { + 'node with embedded subject having no @id': { input: %({ "@id": { "ex:prop": "value" @@ -1334,9 +1338,9 @@ }), expected: %( <<_:b0 "value">> "value2" . - ), + ) }, - "node with embedded subject having IRI @id": { + 'node with embedded subject having IRI @id': { input: %({ "@id": { "@id": "ex:rei", @@ -1346,9 +1350,9 @@ }), expected: %( << "value">> "value2" . - ), + ) }, - "node with embedded subject having BNode @id": { + 'node with embedded subject having BNode @id': { input: %({ "@id": { "@id": "_:rei", @@ -1358,9 +1362,9 @@ }), expected: %( <<_:b0 "value">> "value2" . - ), + ) }, - "node with embedded subject having a type": { + 'node with embedded subject having a type': { input: %({ "@id": { "@id": "ex:rei", @@ -1370,9 +1374,9 @@ }), expected: %( << >> "value2" . - ), + ) }, - "node with embedded subject having an IRI value": { + 'node with embedded subject having an IRI value': { input: %({ "@id": { "@id": "ex:rei", @@ -1382,9 +1386,9 @@ }), expected: %( << >> "value2" . - ), + ) }, - "node with embedded subject having an BNode value": { + 'node with embedded subject having an BNode value': { input: %({ "@id": { "@id": "ex:rei", @@ -1394,9 +1398,9 @@ }), expected: %( << _:b0>> "value2" . - ), + ) }, - "node with recursive embedded subject": { + 'node with recursive embedded subject': { input: %({ "@id": { "@id": { @@ -1409,9 +1413,9 @@ }), expected: %( <<<< "value3">> "value">> "value2" . - ), + ) }, - "illegal node with subject having no property": { + 'illegal node with subject having no property': { input: %({ "@id": { "@id": "ex:rei" @@ -1420,7 +1424,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having multiple properties": { + 'illegal node with subject having multiple properties': { input: %({ "@id": { "@id": "ex:rei", @@ -1430,7 +1434,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having multiple types": { + 'illegal node with subject having multiple types': { input: %({ "@id": { "@id": "ex:rei", @@ -1440,7 +1444,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "illegal node with subject having type and property": { + 'illegal node with subject having type and property': { input: %({ "@id": { "@id": "ex:rei", @@ -1451,7 +1455,7 @@ }), exception: JSON::LD::JsonLdError::InvalidEmbeddedNode }, - "node with embedded object": { + 'node with embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -1463,9 +1467,9 @@ }), expected: %( << "value">> . - ), + ) }, - "node with embedded object having properties": { + 'node with embedded object having properties': { input: %({ "@id": "ex:subj", "ex:value": { @@ -1479,9 +1483,9 @@ expected: %( << "value">> . << "value">> "value2" . - ), + ) }, - "node with recursive embedded object": { + 'node with recursive embedded object': { input: %({ "@id": "ex:subj", "ex:value": { @@ -1498,18 +1502,22 @@ expected: %( <<<< "value3">> "value">> . <<<< "value3">> "value">> "value2" . - ), - }, + ) + } }.each do |title, params| context(title) do - it "Generates statements" do - output_graph = RDF::Graph.new {|g| g << RDF::NTriples::Reader.new(params[:expected], rdfstar: true)} - run_to_rdf params.merge(rdfstar: true, output: output_graph) - end if params[:expected] + if params[:expected] + it "Generates statements" do + output_graph = RDF::Graph.new { |g| g << RDF::NTriples::Reader.new(params[:expected], rdfstar: true) } + run_to_rdf params.merge(rdfstar: true, output: output_graph) + end + end - it "Exception" do - run_to_rdf params.merge(rdfstar: true) - end if params[:exception] + if params[:exception] + it "Exception" do + run_to_rdf params.merge(rdfstar: true) + end + end end end end @@ -1566,7 +1574,7 @@ }), output: %(), pending: "jruby" - }, + } }.each do |title, params| it(title) do pending params[:pending] if params[:pending] == RUBY_ENGINE @@ -1578,7 +1586,7 @@ context "html" do { - "Transforms embedded JSON-LD script element": { + 'Transforms embedded JSON-LD script element': { input: %( @@ -1594,7 +1602,7 @@ ), output: %([ ( "bar")] .) }, - "Transforms first script element with extractAllScripts: false": { + 'Transforms first script element with extractAllScripts: false': { input: %( @@ -1620,7 +1628,7 @@ output: %([ ( "bar")] .), extractAllScripts: false }, - "Transforms targeted script element": { + 'Transforms targeted script element': { input: %( @@ -1648,11 +1656,11 @@ [ "bar"] . ), base: "http://example.org/doc#second" - }, + } }.each do |title, params| it(title) do params[:input] = StringIO.new(params[:input]) - params[:input].send(:define_singleton_method, :content_type) {"text/html"} + params[:input].send(:define_singleton_method, :content_type) { "text/html" } run_to_rdf params.merge(validate: true) end end @@ -1660,23 +1668,32 @@ def parse(input, **options) graph = options[:graph] || RDF::Graph.new - options = {logger: logger, validate: true, canonicalize: false}.merge(options) - JSON::LD::API.toRdf(StringIO.new(input), rename_bnodes: false, **options) {|st| graph << st} + options = { logger: logger, validate: true, canonicalize: false }.merge(options) + JSON::LD::API.toRdf(StringIO.new(input), rename_bnodes: false, **options) { |st| graph << st } graph end def run_to_rdf(params) - input, output = params[:input], params[:output] + input = params[:input] + output = params[:output] graph = params[:graph] || RDF::Graph.new input = StringIO.new(input) if input.is_a?(String) pending params.fetch(:pending, "test implementation") unless input if params[:exception] - expect {JSON::LD::API.toRdf(input, **params)}.to raise_error(params[:exception]) + expect { JSON::LD::API.toRdf(input, **params) }.to raise_error(params[:exception]) else if params[:write] - expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.to write(params[:write]).to(:error) + expect do + JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) do |st| + graph << st + end + end.to write(params[:write]).to(:error) else - expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.not_to write.to(:error) + expect do + JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) do |st| + graph << st + end + end.not_to write.to(:error) end expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input) end diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index e18222e2..3ecca30e 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -1,24 +1,25 @@ -# coding: utf-8 +# frozen_string_literal: true + require_relative 'spec_helper' require 'rdf/spec/writer' describe JSON::LD::Writer do - let(:logger) {RDF::Spec.logger} + let(:logger) { RDF::Spec.logger } - after(:each) {|example| puts logger.to_s if example.exception} + after { |example| puts logger if example.exception } it_behaves_like 'an RDF::Writer' do - let(:writer) {JSON::LD::Writer.new(StringIO.new, logger: logger)} + let(:writer) { described_class.new(StringIO.new, logger: logger) } end describe ".for" do [ :jsonld, "etc/doap.jsonld", - {file_name: 'etc/doap.jsonld'}, - {file_extension: 'jsonld'}, - {content_type: 'application/ld+json'}, - {content_type: 'application/x-ld+json'}, + { file_name: 'etc/doap.jsonld' }, + { file_extension: 'jsonld' }, + { content_type: 'application/ld+json' }, + { content_type: 'application/x-ld+json' } ].each do |arg| it "discovers with #{arg.inspect}" do expect(RDF::Reader.for(arg)).to eq JSON::LD::Reader @@ -27,26 +28,26 @@ end context "simple tests" do - it "should use full URIs without base" do + it "uses full URIs without base" do input = %( .) expect(serialize(input)).to produce_jsonld([{ - '@id' => "http://a/b", - "http://a/c" => [{"@id" => "http://a/d"}] + '@id' => "http://a/b", + "http://a/c" => [{ "@id" => "http://a/d" }] }], logger) end - it "should use qname URIs with standard prefix" do + it "uses qname URIs with standard prefix" do input = %( .) expect(serialize(input, standard_prefixes: true)).to produce_jsonld({ '@context' => { - "foaf" => "http://xmlns.com/foaf/0.1/", + "foaf" => "http://xmlns.com/foaf/0.1/" }, - '@id' => "foaf:b", - "foaf:c" => {"@id" => "foaf:d"} + '@id' => "foaf:b", + "foaf:c" => { "@id" => "foaf:d" } }, logger) end - it "should use qname URIs with parsed prefix" do + it "uses qname URIs with parsed prefix" do input = %( . "Rhythm Paradise"@en . @@ -54,52 +55,52 @@ "rhythm-tengoku" . ) expect(serialize(input, prefixes: { - dc: "http://purl.org/dc/terms/", - frbr: "http://vocab.org/frbr/core#", - senet: "https://senet.org/ns#", + dc: "http://purl.org/dc/terms/", + frbr: "http://vocab.org/frbr/core#", + senet: "https://senet.org/ns#" })).to produce_jsonld({ '@context' => { "dc" => "http://purl.org/dc/terms/", "frbr" => "http://vocab.org/frbr/core#", "senet" => "https://senet.org/ns#" }, - '@id' => "https://senet.org/gm", - "@type" => "frbr:Work", - "dc:title" => {"@value" => "Rhythm Paradise","@language" => "en"}, - "senet:unofficialTitle" => {"@value" => "Rhythm Tengoku","@language" => "en"}, + '@id' => "https://senet.org/gm", + "@type" => "frbr:Work", + "dc:title" => { "@value" => "Rhythm Paradise", "@language" => "en" }, + "senet:unofficialTitle" => { "@value" => "Rhythm Tengoku", "@language" => "en" }, "senet:urlkey" => "rhythm-tengoku" }, logger) end - it "should use CURIEs with empty prefix" do + it "uses CURIEs with empty prefix" do input = %( .) begin - expect(serialize(input, prefixes: { "" => RDF::Vocab::FOAF})). - to produce_jsonld({ - "@context" => { - "" => "http://xmlns.com/foaf/0.1/" - }, - '@id' => ":b", - ":c" => {"@id" => ":d"} - }, logger) + expect(serialize(input, prefixes: { "" => RDF::Vocab::FOAF })) + .to produce_jsonld({ + "@context" => { + "" => "http://xmlns.com/foaf/0.1/" + }, + '@id' => ":b", + ":c" => { "@id" => ":d" } + }, logger) rescue JSON::LD::JsonLdError, JSON::LD::JsonLdError, TypeError => e - fail("#{e.class}: #{e.message}\n" + - "#{logger}\n" + - "Backtrace:\n#{e.backtrace.join("\n")}") + raise("#{e.class}: #{e.message}\n" \ + "#{logger}\n" \ + "Backtrace:\n#{e.backtrace.join("\n")}") end end - - it "should not use terms if no suffix" do + + it "does not use terms if no suffix" do input = %( .) - expect(serialize(input, standard_prefixes: true)). - not_to produce_jsonld({ - "@context" => {"foaf" => "http://xmlns.com/foaf/0.1/"}, - '@id' => "foaf", - "foaf" => {"@id" => "foaf"} - }, logger) + expect(serialize(input, standard_prefixes: true)) + .not_to produce_jsonld({ + "@context" => { "foaf" => "http://xmlns.com/foaf/0.1/" }, + '@id' => "foaf", + "foaf" => { "@id" => "foaf" } + }, logger) end - - it "should not use CURIE with illegal local part" do + + it "does not use CURIE with illegal local part" do input = %( @prefix db: . @prefix dbo: . @@ -107,46 +108,47 @@ ) expect(serialize(input, prefixes: { - "db" => RDF::URI("http://dbpedia.org/resource/"), - "dbo" => RDF::URI("http://dbpedia.org/ontology/")})). - to produce_jsonld({ - "@context" => { - "db" => "http://dbpedia.org/resource/", - "dbo" => "http://dbpedia.org/ontology/" - }, - '@id' => "db:Michael_Jackson", - "dbo:artistOf" => {"@id" => "db:%28I_Can%27t_Make_It%29_Another_Day"} - }, logger) + "db" => RDF::URI("http://dbpedia.org/resource/"), + "dbo" => RDF::URI("http://dbpedia.org/ontology/") + })) + .to produce_jsonld({ + "@context" => { + "db" => "http://dbpedia.org/resource/", + "dbo" => "http://dbpedia.org/ontology/" + }, + '@id' => "db:Michael_Jackson", + "dbo:artistOf" => { "@id" => "db:%28I_Can%27t_Make_It%29_Another_Day" } + }, logger) end - it "should not use provided node identifiers if :unique_bnodes set" do - input = %(_:a _:b \.) + it "does not use provided node identifiers if :unique_bnodes set" do + input = %(_:a _:b .) result = serialize(input, unique_bnodes: true, context: {}) - expect(result.to_json).to match(%r(_:g\w+)) + expect(result.to_json).to match(/_:g\w+/) end it "serializes multiple subjects" do - input = %q( + input = ' @prefix : . @prefix dc: . a :TestCase . a :TestCase . - ) - expect(serialize(input, prefixes: {"" => "http://www.w3.org/2006/03/test-description#"})). - to produce_jsonld({ - '@context' => { - "" => "http://www.w3.org/2006/03/test-description#", - "dc" => RDF::Vocab::DC.to_s - }, - '@graph' => [ - {'@id' => "http://example.com/test-cases/0001", '@type' => ":TestCase"}, - {'@id' => "http://example.com/test-cases/0002", '@type' => ":TestCase"} - ] - }, logger) + ' + expect(serialize(input, prefixes: { "" => "http://www.w3.org/2006/03/test-description#" })) + .to produce_jsonld({ + '@context' => { + "" => "http://www.w3.org/2006/03/test-description#", + "dc" => RDF::Vocab::DC.to_s + }, + '@graph' => [ + { '@id' => "http://example.com/test-cases/0001", '@type' => ":TestCase" }, + { '@id' => "http://example.com/test-cases/0002", '@type' => ":TestCase" } + ] + }, logger) end it "serializes Wikia OWL example" do - input = %q( + input = ' @prefix owl: . @prefix rdf: . @prefix rdfs: . @@ -158,47 +160,49 @@ owl:minQualifiedCardinality "1"^^xsd:nonNegativeInteger; owl:onClass ; owl:onProperty . - ) + ' expect(serialize(input, rename_bnodes: false, prefixes: { - owl: "http://www.w3.org/2002/07/owl#", + owl: "http://www.w3.org/2002/07/owl#", rdfs: "http://www.w3.org/2000/01/rdf-schema#", - xsd: "http://www.w3.org/2001/XMLSchema#" - })). - to produce_jsonld({ - '@context' => { - "owl" => "http://www.w3.org/2002/07/owl#", - "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", - "rdfs" => "http://www.w3.org/2000/01/rdf-schema#", - "xsd" => "http://www.w3.org/2001/XMLSchema#" - }, - '@graph' => [ - { - "@id" => "_:a", - "@type" => "owl:Restriction", - "owl:minQualifiedCardinality" => {"@value" => "1","@type" => "xsd:nonNegativeInteger"}, - "owl:onClass" => {"@id" => "http://data.wikia.com/terms#Element"}, - "owl:onProperty" => {"@id" => "http://data.wikia.com/terms#characterIn"} + xsd: "http://www.w3.org/2001/XMLSchema#" + })) + .to produce_jsonld({ + '@context' => { + "owl" => "http://www.w3.org/2002/07/owl#", + "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs" => "http://www.w3.org/2000/01/rdf-schema#", + "xsd" => "http://www.w3.org/2001/XMLSchema#" }, - { - "@id" => "http://data.wikia.com/terms#Character", - "@type" => "owl:Class", - "rdfs:subClassOf" => {"@id" => "_:a"} - } - ] - }, logger) + '@graph' => [ + { + "@id" => "_:a", + "@type" => "owl:Restriction", + "owl:minQualifiedCardinality" => { "@value" => "1", "@type" => "xsd:nonNegativeInteger" }, + "owl:onClass" => { "@id" => "http://data.wikia.com/terms#Element" }, + "owl:onProperty" => { "@id" => "http://data.wikia.com/terms#characterIn" } + }, + { + "@id" => "http://data.wikia.com/terms#Character", + "@type" => "owl:Class", + "rdfs:subClassOf" => { "@id" => "_:a" } + } + ] + }, logger) end end context "RDF-star" do { - "subject-iii": { + 'subject-iii': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -208,14 +212,16 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-iib": { + 'subject-iib': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1')), + RDF::Node.new('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -225,14 +231,16 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-iil": { + 'subject-iil': { input: RDF::Statement( RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1')), + RDF::Literal('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -242,14 +250,16 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bii": { + 'subject-bii': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -259,13 +269,15 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bib": { + 'subject-bib': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1')), - RDF::URI('http://example/p'), RDF::URI('http://example/o')), + RDF::Node.new('o1') + ), + RDF::URI('http://example/p'), RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -275,14 +287,16 @@ "ex:p": {"@id": "ex:o"} }) }, - "subject-bil": { + 'subject-bil': { input: RDF::Statement( RDF::Statement( RDF::Node('s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1')), + RDF::Literal('o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -292,14 +306,16 @@ "ex:p": {"@id": "ex:o"} }) }, - "object-iii": { + 'object-iii': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1'))), + RDF::URI('http://example/o1') + ) + ), output: %({ "@context": {"ex": "http://example/"}, "@id": "ex:s", @@ -311,14 +327,16 @@ } }) }, - "object-iib": { + 'object-iib': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Node.new('o1'))), + RDF::Node.new('o1') + ) + ), output: %({ "@context": {"ex": "http://example/"}, "@id": "ex:s", @@ -330,14 +348,16 @@ } }) }, - "object-iil": { + 'object-iil': { input: RDF::Statement( RDF::URI('http://example/s'), RDF::URI('http://example/p'), RDF::Statement( RDF::URI('http://example/s1'), RDF::URI('http://example/p1'), - RDF::Literal('o1'))), + RDF::Literal('o1') + ) + ), output: %({ "@context": {"ex": "http://example/"}, "@id": "ex:s", @@ -349,17 +369,20 @@ } }) }, - "recursive-subject": { + 'recursive-subject': { input: RDF::Statement( RDF::Statement( RDF::Statement( RDF::URI('http://example/s2'), RDF::URI('http://example/p2'), - RDF::URI('http://example/o2')), + RDF::URI('http://example/o2') + ), RDF::URI('http://example/p1'), - RDF::URI('http://example/o1')), + RDF::URI('http://example/o1') + ), RDF::URI('http://example/p'), - RDF::URI('http://example/o')), + RDF::URI('http://example/o') + ), output: %({ "@context": {"ex": "http://example/"}, "@id": { @@ -371,40 +394,43 @@ }, "ex:p": {"@id": "ex:o"} }) - }, + } }.each do |name, params| it name do - graph = RDF::Graph.new {|g| g << params[:input]} + graph = RDF::Graph.new { |g| g << params[:input] } expect( - serialize(graph, rdfstar: true, prefixes: {ex: 'http://example/'}) + serialize(graph, rdfstar: true, prefixes: { ex: 'http://example/' }) ).to produce_jsonld(JSON.parse(params[:output]), logger) end end end - context "Writes fromRdf tests to isomorphic graph" do - require 'suite_helper' - m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") - describe m.name do - m.entries.each do |t| - next unless t.positiveTest? && !t.property('input').include?('0016') - specify "#{t.property('@id')}: #{t.name}" do - logger.info "test: #{t.inspect}" - logger.info "source: #{t.input}" - t.logger = logger - pending "Shared list BNode in different graphs" if t.property('input').include?("fromRdf-0021") - repo = RDF::Repository.load(t.input_loc, format: :nquads) - jsonld = JSON::LD::Writer.buffer(logger: t.logger, **t.options) do |writer| - writer << repo - end + unless ENV['CI'] + context "Writes fromRdf tests to isomorphic graph" do + require 'suite_helper' + m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld") + describe m.name do + m.entries.each do |t| + next unless t.positiveTest? && !t.property('input').include?('0016') + + specify "#{t.property('@id')}: #{t.name}" do + logger.info "test: #{t.inspect}" + logger.info "source: #{t.input}" + t.logger = logger + pending "Shared list BNode in different graphs" if t.property('input').include?("fromRdf-0021") + repo = RDF::Repository.load(t.input_loc, format: :nquads) + jsonld = described_class.buffer(logger: t.logger, **t.options) do |writer| + writer << repo + end - # And then, re-generate jsonld as RDF - - expect(parse(jsonld, format: :jsonld, **t.options)).to be_equivalent_graph(repo, t) + # And then, re-generate jsonld as RDF + + expect(parse(jsonld, format: :jsonld, **t.options)).to be_equivalent_graph(repo, t) + end end end end - end unless ENV['CI'] + end def parse(input, format: :trig, **options) reader = RDF::Reader.for(format) @@ -414,14 +440,14 @@ def parse(input, format: :trig, **options) # Serialize ntstr to a string and compare against regexps def serialize(ntstr, **options) g = ntstr.is_a?(String) ? parse(ntstr, **options) : ntstr - #logger.info g.dump(:ttl) + # logger.info g.dump(:ttl) result = JSON::LD::Writer.buffer(logger: logger, **options) do |writer| writer << g end if $verbose - #puts hash.to_json + # puts hash.to_json end - + JSON.parse(result) end end