json-ld 3.1.1 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 686aaec1dba1b51a5f37e1d4ebd28395c189c0944022b1b9877c7c5a8500cef3
4
- data.tar.gz: 5a9f07dd8fc17e3b4b3129b45cbd783e5390b7921da10c62d7d087621e1e123d
3
+ metadata.gz: 80dcb6be296036b1a18ead88bd014259a415329b127f326479239c15aa4d634c
4
+ data.tar.gz: d0b0faa2cf53cca55f62e8a5e149016654796ab726f709ae66a9a4f6aa1b336b
5
5
  SHA512:
6
- metadata.gz: f3bb2f7b57db9b1689e43ceca7fbe497f0c67fffd5c12a8a7b451f07e0acf45be1f45f30d3acfd2e7e5ab1a52b9486954e8af1ebceb40478599b1fa8d9809035
7
- data.tar.gz: 8acfd478567cec305f2a37e189a7ba11c2bb75463746bc1a114be79b71ea3e84b19632224515b0e2097c2a2a16293f098eb06556d74bb6a2a7e32516ad1476d3
6
+ metadata.gz: 29916449e8674ad3df3a8b1a9dd81128e565e40f37c276174f1584113a7933659de51c30d56b9f73e6487f20a711f2bbc1c034d54f64ae6677285a0609513a31
7
+ data.tar.gz: 85dea41c304414e584e6b343f3230e41d88d70e18213a6b916971c76d0be9f7b628bfe7bee022605c0c18d8cdec3b3e102cb6883c128946dbf2f84c8a901e77e
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.1
1
+ 3.1.2
@@ -52,13 +52,13 @@ module JSON
52
52
  @direction
53
53
  @embed
54
54
  @explicit
55
- @json
56
- @id
57
- @included
58
- @index
59
55
  @first
60
56
  @graph
57
+ @id
61
58
  @import
59
+ @included
60
+ @index
61
+ @json
62
62
  @language
63
63
  @list
64
64
  @nest
@@ -66,6 +66,7 @@ module JSON
66
66
  @omitDefault
67
67
  @propagate
68
68
  @protected
69
+ @preserve
69
70
  @requireAll
70
71
  @reverse
71
72
  @set
@@ -154,7 +155,7 @@ module JSON
154
155
  class KeywordRedefinition < JsonLdError; @code = "keyword redefinition"; end
155
156
  class LoadingDocumentFailed < JsonLdError; @code = "loading document failed"; end
156
157
  class LoadingRemoteContextFailed < JsonLdError; @code = "loading remote context failed"; end
157
- class ContextOverflow < JsonLdError; @code = "maximum number of @context URLs exceeded"; end
158
+ class ContextOverflow < JsonLdError; @code = "context overflow"; end
158
159
  class MissingIncludedReferent < JsonLdError; @code = "missing @included referent"; end
159
160
  class MultipleContextLinkHeaders < JsonLdError; @code = "multiple context link headers"; end
160
161
  class ProtectedTermRedefinition < JsonLdError; @code = "protected term redefinition"; end
@@ -703,14 +703,14 @@ module JSON::LD
703
703
  require "json/ld/html/#{library}"
704
704
 
705
705
  # Parse HTML using the appropriate library
706
- @implementation = case library
706
+ implementation = case library
707
707
  when :nokogiri then Nokogiri
708
708
  when :rexml then REXML
709
709
  end
710
- self.extend(@implementation)
710
+ self.extend(implementation)
711
711
 
712
712
  input = begin
713
- initialize_html(input, **options)
713
+ self.send("initialize_html_#{library}".to_sym, input, **options)
714
714
  rescue
715
715
  raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Malformed HTML document: #{$!.message}"
716
716
  end
@@ -729,8 +729,8 @@ module JSON::LD
729
729
  id = CGI.unescape(url.fragment)
730
730
  # Find script with an ID based on that fragment.
731
731
  element = input.at_xpath("//script[@id='#{id}']")
732
- raise JSON::LD::JsonLdError::InvalidScriptElement, "No script tag found with id=#{id}" unless element
733
- raise JSON::LD::JsonLdError::InvalidScriptElement, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json')
732
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found with id=#{id}" unless element
733
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json')
734
734
  content = element.inner_html
735
735
  validate_input(content, url: url) if options[:validate]
736
736
  MultiJson.load(content, **options)
@@ -759,11 +759,12 @@ module JSON::LD
759
759
  # Find the first script with type application/ld+json.
760
760
  element = input.at_xpath("//script[starts-with(@type, 'application/ld+json;profile=#{profile}')]") if profile
761
761
  element ||= input.at_xpath("//script[starts-with(@type, 'application/ld+json')]")
762
- content = element ? element.inner_html : "[]"
762
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
763
+ content = element.inner_html
763
764
  validate_input(content, url: url) if options[:validate]
764
765
  MultiJson.load(content, **options)
765
766
  end
766
- rescue JSON::LD::JsonLdError::LoadingDocumentFailed, MultiJson::ParseError => e
767
+ rescue MultiJson::ParseError => e
767
768
  raise JSON::LD::JsonLdError::InvalidScriptElement, e.message
768
769
  end
769
770
 
@@ -526,11 +526,19 @@ module JSON::LD
526
526
  # @param [Boolean] override_protected Protected terms may be cleared.
527
527
  # @param [Boolean] propagate
528
528
  # If false, retains any previously defined term, which can be rolled back when the descending into a new node object changes.
529
+ # @param [Boolean] validate_scoped (true).
530
+ # Validate scoped context, loading if necessary.
531
+ # If false, do not load scoped contexts.
529
532
  # @raise [JsonLdError]
530
533
  # on a remote context load error, syntax error, or a reference to a term which is not defined.
531
534
  # @return [Context]
532
535
  # @see https://www.w3.org/TR/json-ld11-api/index.html#context-processing-algorithm
533
- def parse(local_context, remote_contexts: [], protected: false, override_protected: false, propagate: true)
536
+ def parse(local_context,
537
+ remote_contexts: [],
538
+ protected: false,
539
+ override_protected: false,
540
+ propagate: true,
541
+ validate_scoped: true)
534
542
  result = self.dup
535
543
  result.provided_context = local_context if self.empty?
536
544
  # Early check for @propagate, which can only appear in a local context
@@ -576,6 +584,9 @@ module JSON::LD
576
584
  context_canon = context.canonicalize
577
585
  context_canon.scheme == 'http' if context_canon.scheme == 'https'
578
586
 
587
+ # If validating a scoped context which has already been loaded, skip to the next one
588
+ next if !validate_scoped && remote_contexts.include?(context.to_s)
589
+
579
590
  remote_contexts << context.to_s
580
591
  raise JsonLdError::ContextOverflow, "#{context}" if remote_contexts.length >= MAX_CONTEXTS_LOADED
581
592
 
@@ -617,7 +628,12 @@ module JSON::LD
617
628
  end
618
629
 
619
630
  # 3.2.6) Set context to the result of recursively calling this algorithm, passing context no base for active context, context for local context, and remote contexts.
620
- context = context_no_base.parse(context, remote_contexts: remote_contexts.dup, protected: protected, override_protected: override_protected, propagate: propagate)
631
+ context = context_no_base.parse(context,
632
+ remote_contexts: remote_contexts.dup,
633
+ protected: protected,
634
+ override_protected: override_protected,
635
+ propagate: propagate,
636
+ validate_scoped: validate_scoped)
621
637
  PRELOADED[context_canon.to_s] = context.dup
622
638
  context.provided_context = result.provided_context
623
639
  end
@@ -678,7 +694,10 @@ module JSON::LD
678
694
  # ... where key is not @base, @vocab, @language, or @version
679
695
  result.create_term_definition(context, key, defined,
680
696
  override_protected: override_protected,
681
- protected: context.fetch('@protected', protected)) unless NON_TERMDEF_KEYS.include?(key)
697
+ protected: context.fetch('@protected', protected),
698
+ remote_contexts: remote_contexts.dup,
699
+ validate_scoped: validate_scoped
700
+ ) unless NON_TERMDEF_KEYS.include?(key)
682
701
  end
683
702
  else
684
703
  # 3.3) If context is not a JSON object, an invalid local context error has been detected and processing is aborted.
@@ -740,10 +759,18 @@ module JSON::LD
740
759
  # @param [Boolean] override_protected Protected terms may be cleared.
741
760
  # @param [Boolean] propagate
742
761
  # Context is propagated across node objects.
762
+ # @param [Array<String>] remote_contexts
763
+ # @param [Boolean] validate_scoped (true).
764
+ # Validate scoped context, loading if necessary.
765
+ # If false, do not load scoped contexts.
743
766
  # @raise [JsonLdError]
744
767
  # Represents a cyclical term dependency
745
768
  # @see https://www.w3.org/TR/json-ld11-api/index.html#create-term-definition
746
- def create_term_definition(local_context, term, defined, override_protected: false, protected: false)
769
+ def create_term_definition(local_context, term, defined,
770
+ override_protected: false,
771
+ protected: false,
772
+ remote_contexts: [],
773
+ validate_scoped: true)
747
774
  # Expand a string value, unless it matches a keyword
748
775
  #log_debug("create_term_definition") {"term = #{term.inspect}"}
749
776
 
@@ -763,6 +790,7 @@ module JSON::LD
763
790
  # Since keywords cannot be overridden, term must not be a keyword. Otherwise, an invalid value has been detected, which is an error.
764
791
  if term == '@type' &&
765
792
  value.is_a?(Hash) &&
793
+ !value.empty? &&
766
794
  processingMode("json-ld-1.1") &&
767
795
  (value.keys - %w(@container @protected)).empty? &&
768
796
  value.fetch('@container', '@set') == '@set'
@@ -841,6 +869,11 @@ module JSON::LD
841
869
  raise JsonLdError::InvalidIRIMapping, "expected value of @reverse to be a string: #{value['@reverse'].inspect} on term #{term.inspect}" unless
842
870
  value['@reverse'].is_a?(String)
843
871
 
872
+ if value['@reverse'].to_s.match?(/^@[a-zA-Z]+$/) && @options[:validate]
873
+ warn "Values beginning with '@' are reserved for future use and ignored: #{value['@reverse']}."
874
+ return
875
+ end
876
+
844
877
  # Otherwise, set the IRI mapping of definition to the result of using the IRI Expansion algorithm, passing active context, the value associated with the @reverse key for value, true for vocab, true for document relative, local context, and defined. If the result is not an absolute IRI, i.e., it contains no colon (:), an invalid IRI mapping error has been detected and processing is aborted.
845
878
  definition.id = expand_iri(value['@reverse'],
846
879
  vocab: true,
@@ -849,11 +882,6 @@ module JSON::LD
849
882
  raise JsonLdError::InvalidIRIMapping, "non-absolute @reverse IRI: #{definition.id} on term #{term.inspect}" unless
850
883
  definition.id.is_a?(RDF::Node) || definition.id.is_a?(RDF::URI) && definition.id.absolute?
851
884
 
852
- if value['@reverse'].to_s.match?(/^@[a-zA-Z]+$/) && @options[:validate]
853
- warn "Values beginning with '@' are reserved for future use and ignored: #{value['@reverse']}."
854
- return
855
- end
856
-
857
885
  if term[1..-1].to_s.include?(':') && (term_iri = expand_iri(term)) != definition.id
858
886
  raise JsonLdError::InvalidIRIMapping, "term #{term} expands to #{definition.id}, not #{term_iri}"
859
887
  end
@@ -957,7 +985,7 @@ module JSON::LD
957
985
 
958
986
  if value.has_key?('@context')
959
987
  begin
960
- self.parse(value['@context'], override_protected: true)
988
+ self.parse(value['@context'], override_protected: true, remote_contexts: remote_contexts, validate_scoped: false)
961
989
  # Record null context in array form
962
990
  definition.context = value['@context'] ? value['@context'] : [nil]
963
991
  rescue JsonLdError => e
@@ -1228,7 +1256,7 @@ module JSON::LD
1228
1256
  term.nest
1229
1257
  else
1230
1258
  nest_term = find_definition(term.nest)
1231
- raise JsonLdError::InvalidNestValue, "nest must a term resolving to @nest, was #{nest_term.inspect}" unless nest_term && nest_term.simple? && nest_term.id == '@nest'
1259
+ raise JsonLdError::InvalidNestValue, "nest must a term resolving to @nest, was #{nest_term.inspect}" unless nest_term && nest_term.id == '@nest'
1232
1260
  term.nest
1233
1261
  end
1234
1262
  end
@@ -1819,7 +1847,7 @@ module JSON::LD
1819
1847
  # @param [String] term
1820
1848
  # @return [Boolean]
1821
1849
  def term_valid?(term)
1822
- term.is_a?(String)
1850
+ term.is_a?(String) && !term.empty?
1823
1851
  end
1824
1852
 
1825
1853
  # Reverse term mapping, typically used for finding aliases for keys.
@@ -625,11 +625,13 @@ module JSON::LD
625
625
 
626
626
  # For each key in nests, recusively expand content
627
627
  nests.each do |key|
628
+ nest_context = context.term_definitions[key].context if context.term_definitions[key]
629
+ nest_context = nest_context ? context.parse(nest_context, override_protected: true) : context
628
630
  nested_values = as_array(input[key])
629
631
  nested_values.each do |nv|
630
632
  raise JsonLdError::InvalidNestValue, nv.inspect unless
631
- nv.is_a?(Hash) && nv.keys.none? {|k| context.expand_iri(k, vocab: true) == '@value'}
632
- expand_object(nv, active_property, context, output_object,
633
+ nv.is_a?(Hash) && nv.keys.none? {|k| nest_context.expand_iri(k, vocab: true) == '@value'}
634
+ expand_object(nv, active_property, nest_context, output_object,
633
635
  expanded_active_property: expanded_active_property,
634
636
  type_scoped_context: type_scoped_context,
635
637
  type_key: type_key,
@@ -142,7 +142,7 @@ module JSON::LD
142
142
 
143
143
  # Iterate over node properties
144
144
  node.each do |property, values|
145
- if property.start_with?('@')
145
+ if property != '@type' && property.start_with?('@')
146
146
  # Copy keywords
147
147
  merged_node[property] = node[property].dup
148
148
  else
@@ -114,7 +114,6 @@ module JSON::LD
114
114
  end
115
115
 
116
116
  if recurse
117
- state[:graphStack].push(state[:graph])
118
117
  frame(state.merge(graph: id, embedded: false), state[:graphMap][id].keys, [subframe], parent: output, property: '@graph', **options)
119
118
  end
120
119
  end
@@ -129,7 +129,7 @@ module JSON::LD
129
129
  #
130
130
  # @param [Hash{Symbol => Object}] options
131
131
  # @return [NodeProxy] of root element
132
- def initialize_html(input, options = {})
132
+ def initialize_html_nokogiri(input, options = {})
133
133
  require 'nokogiri' unless defined?(::Nokogiri)
134
134
  doc = case input
135
135
  when ::Nokogiri::HTML::Document, ::Nokogiri::XML::Document
@@ -146,6 +146,7 @@ module JSON::LD
146
146
 
147
147
  NodeProxy.new(doc.root) if doc && doc.root
148
148
  end
149
+ alias_method :initialize_html, :initialize_html_nokogiri
149
150
  end
150
151
  end
151
152
  end
@@ -169,7 +169,7 @@ module JSON::LD
169
169
  #
170
170
  # @param [Hash{Symbol => Object}] options
171
171
  # @return [NodeProxy] of document root
172
- def initialize_html(input, options = {})
172
+ def initialize_html_rexml(input, options = {})
173
173
  require 'rexml/document' unless defined?(::REXML)
174
174
  doc = case input
175
175
  when ::REXML::Document
@@ -181,6 +181,7 @@ module JSON::LD
181
181
 
182
182
  NodeProxy.new(doc.root) if doc && doc.root
183
183
  end
184
+ alias_method :initialize_html, :initialize_html_rexml
184
185
  end
185
186
  end
186
187
  end
@@ -503,7 +503,7 @@ describe JSON::LD::Context do
503
503
  "@type as object" => {"foo" => {"@type" => {}}},
504
504
  "@type as array" => {"foo" => {"@type" => []}},
505
505
  "@type as @list" => {"foo" => {"@type" => "@list"}},
506
- "@type as @none" => {"@version": 1.1, "foo" => {"@type" => "@none"}},
506
+ "@type as @none" => {"@version" => 1.1, "foo" => {"@type" => "@none"}},
507
507
  "@type as @set" => {"foo" => {"@type" => "@set"}},
508
508
  "@container as object" => {"foo" => {"@container" => {}}},
509
509
  "@container as empty array" => {"foo" => {"@container" => []}},
@@ -954,11 +954,13 @@ describe JSON::LD::Context do
954
954
  }, logger)
955
955
  end
956
956
 
957
- context "extra keys or values" do
957
+ context "invalid term definitions" do
958
958
  {
959
- "extra key" => {
960
- input: {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}},
961
- result: {"@context" => {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}}}
959
+ "empty term": {
960
+ input: {"" => "http://blank-term/"}
961
+ },
962
+ "extra key": {
963
+ input: {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}}
962
964
  }
963
965
  }.each do |title, params|
964
966
  it title do
@@ -975,7 +977,6 @@ describe JSON::LD::Context do
975
977
  '@base' => 'http://base/',
976
978
  '@vocab' => 'http://vocab/',
977
979
  'ex' => 'http://example.org/',
978
- '' => 'http://empty/',
979
980
  '_' => 'http://underscore/'
980
981
  })
981
982
  }
@@ -1039,7 +1040,6 @@ describe JSON::LD::Context do
1039
1040
  '@base' => 'http://base/base',
1040
1041
  '@vocab' => 'http://vocab/',
1041
1042
  'ex' => 'http://example.org/',
1042
- '' => 'http://empty/',
1043
1043
  '_' => 'http://underscore/'
1044
1044
  })
1045
1045
  }
@@ -1119,7 +1119,6 @@ describe JSON::LD::Context do
1119
1119
  "unmapped" => ["foo", RDF::URI("http://vocab/foo")],
1120
1120
  "relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")],
1121
1121
  "dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")],
1122
- "empty term" => ["", RDF::URI("http://empty/")],
1123
1122
  "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
1124
1123
  "absolute IRI looking like a compact IRI" =>
1125
1124
  ["foo:bar", RDF::URI("foo:bar")],
@@ -1138,7 +1137,6 @@ describe JSON::LD::Context do
1138
1137
  '@base' => 'http://base/base',
1139
1138
  '@vocab' => '',
1140
1139
  'ex' => 'http://example.org/',
1141
- '' => 'http://empty/',
1142
1140
  '_' => 'http://underscore/'
1143
1141
  })
1144
1142
  }
@@ -1153,7 +1151,6 @@ describe JSON::LD::Context do
1153
1151
  "unmapped" => ["foo", RDF::URI("http://base/basefoo")],
1154
1152
  "relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")],
1155
1153
  "dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")],
1156
- "empty term" => ["", RDF::URI("http://empty/")],
1157
1154
  "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
1158
1155
  "absolute IRI looking like a compact IRI" =>
1159
1156
  ["foo:bar", RDF::URI("foo:bar")],
@@ -1183,7 +1180,6 @@ describe JSON::LD::Context do
1183
1180
  '@base' => 'http://base/',
1184
1181
  "xsd" => "http://www.w3.org/2001/XMLSchema#",
1185
1182
  'ex' => 'http://example.org/',
1186
- '' => 'http://empty/',
1187
1183
  '_' => 'http://underscore/',
1188
1184
  'rex' => {'@reverse' => "ex"},
1189
1185
  'lex' => {'@id' => 'ex', '@language' => 'en'},
@@ -1390,7 +1386,6 @@ describe JSON::LD::Context do
1390
1386
  "absolute IRI" => ["http://example.com/", "http://example.com/"],
1391
1387
  "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
1392
1388
  "keyword" => ["@type", "@type"],
1393
- "empty" => [":suffix", "http://empty/suffix"],
1394
1389
  "unmapped" => ["foo", "foo"],
1395
1390
  "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
1396
1391
  "relative" => ["foo/bar", "http://base/foo/bar"],
@@ -1412,7 +1407,6 @@ describe JSON::LD::Context do
1412
1407
  "absolute IRI" => ["http://example.com/", "http://example.com/"],
1413
1408
  "prefix:suffix" => ["suffix", "http://example.org/suffix"],
1414
1409
  "keyword" => ["@type", "@type"],
1415
- "empty" => [":suffix", "http://empty/suffix"],
1416
1410
  "unmapped" => ["foo", "foo"],
1417
1411
  "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
1418
1412
  "relative" => ["http://base/foo/bar", "http://base/foo/bar"],
@@ -2909,6 +2909,26 @@ describe JSON::LD::API do
2909
2909
  validate: true,
2910
2910
  exception: JSON::LD::JsonLdError::InvalidTermDefinition
2911
2911
  },
2912
+ "Applies property scoped contexts which are aliases of @nest": {
2913
+ input: %({
2914
+ "@context": {
2915
+ "@version": 1.1,
2916
+ "@vocab": "http://example.org/",
2917
+ "nest": {
2918
+ "@id": "@nest",
2919
+ "@context": {
2920
+ "@vocab": "http://example.org/nest/"
2921
+ }
2922
+ }
2923
+ },
2924
+ "nest": {
2925
+ "property": "should be in /nest"
2926
+ }
2927
+ }),
2928
+ output: %([{
2929
+ "http://example.org/nest/property": [{"@value": "should be in /nest"}]
2930
+ }])
2931
+ }
2912
2932
  }.each do |title, params|
2913
2933
  it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2914
2934
  end
@@ -3366,7 +3386,7 @@ describe JSON::LD::API do
3366
3386
  %w(Nokogiri REXML).each do |impl|
3367
3387
  next unless Module.constants.map(&:to_s).include?(impl)
3368
3388
  context impl do
3369
- before(:all) {@library = impl.downcase.to_s.to_sym}
3389
+ let(:library) {impl.downcase.to_s.to_sym}
3370
3390
 
3371
3391
  {
3372
3392
  "Expands embedded JSON-LD script element": {
@@ -3505,9 +3525,9 @@ describe JSON::LD::API do
3505
3525
  ]),
3506
3526
  extractAllScripts: true
3507
3527
  },
3508
- "Expands as empty with no script element": {
3528
+ "Errors no script element": {
3509
3529
  input: %(<html><head></head></html>),
3510
- output: %([])
3530
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3511
3531
  },
3512
3532
  "Expands as empty with no script element and extractAllScripts": {
3513
3533
  input: %(<html><head></head></html>),
@@ -3619,7 +3639,7 @@ describe JSON::LD::API do
3619
3639
  </head>
3620
3640
  </html>),
3621
3641
  base: "http://example.org/doc#third",
3622
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3642
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3623
3643
  },
3624
3644
  "Errors if targeted element is not a script element": {
3625
3645
  input: %(
@@ -3636,7 +3656,7 @@ describe JSON::LD::API do
3636
3656
  </head>
3637
3657
  </html>),
3638
3658
  base: "http://example.org/doc#first",
3639
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3659
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3640
3660
  },
3641
3661
  "Errors if targeted element does not have type application/ld+json": {
3642
3662
  input: %(
@@ -3653,7 +3673,7 @@ describe JSON::LD::API do
3653
3673
  </head>
3654
3674
  </html>),
3655
3675
  base: "http://example.org/doc#first",
3656
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3676
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3657
3677
  },
3658
3678
  "Errors if uncommented script text contains comment": {
3659
3679
  input: %(
@@ -3722,10 +3742,10 @@ describe JSON::LD::API do
3722
3742
  },
3723
3743
  }.each do |title, params|
3724
3744
  it(title) do
3725
- skip "rexml" if params[:not] == @library
3726
- params[:input] = StringIO.new(params[:input])
3745
+ skip "rexml" if params[:not] == library
3746
+ params = params.merge(input: StringIO.new(params[:input]))
3727
3747
  params[:input].send(:define_singleton_method, :content_type) {"text/html"}
3728
- run_expand params.merge(validate: true, library: @library)
3748
+ run_expand params.merge(validate: true, library: library)
3729
3749
  end
3730
3750
  end
3731
3751
  end
@@ -2305,6 +2305,50 @@ describe JSON::LD::API do
2305
2305
  }
2306
2306
  }),
2307
2307
  processingMode: "json-ld-1.1"
2308
+ },
2309
+ "missing types": {
2310
+ input: %({
2311
+ "@context": {
2312
+ "ex": "http://example.com#",
2313
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2314
+ },
2315
+ "@graph": [{
2316
+ "@id": "ex:graph1",
2317
+ "@graph": [{
2318
+ "@id": "ex:entity1",
2319
+ "@type": ["ex:Type1","ex:Type2"],
2320
+ "ex:title": "some title",
2321
+ "ex:multipleValues": "ex:One"
2322
+ }]
2323
+ }, {
2324
+ "@id": "ex:graph2",
2325
+ "@graph": [{
2326
+ "@id": "ex:entity1",
2327
+ "@type": "ex:Type3",
2328
+ "ex:tags": "tag1 tag2",
2329
+ "ex:multipleValues": ["ex:Two","ex:Three"]
2330
+ }]
2331
+ }]
2332
+ }),
2333
+ output: %({
2334
+ "@context": {
2335
+ "ex": "http://example.com#",
2336
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2337
+ },
2338
+ "@id": "ex:entity1",
2339
+ "@type": ["ex:Type1", "ex:Type2", "ex:Type3"],
2340
+ "ex:multipleValues": ["ex:One", "ex:Two","ex:Three"],
2341
+ "ex:tags": "tag1 tag2",
2342
+ "ex:title": "some title"
2343
+ }),
2344
+ frame: %({
2345
+ "@context": {
2346
+ "ex": "http://example.com#",
2347
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2348
+ },
2349
+ "@id": "ex:entity1"
2350
+ }),
2351
+ processingMode: "json-ld-1.1"
2308
2352
  }
2309
2353
  }.each do |title, params|
2310
2354
  it title do
@@ -13,7 +13,7 @@ describe JSON::LD do
13
13
  t.options[:ordered] = false
14
14
  if %w(#t0068).include?(t.property('@id'))
15
15
  expect{t.run self}.to write("[DEPRECATION]").to(:error)
16
- elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #t0119 #t0120).include?(t.property('@id'))
16
+ elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120).include?(t.property('@id'))
17
17
  expect{t.run self}.to write("beginning with '@' are reserved for future use").to(:error)
18
18
  else
19
19
  expect {t.run self}.not_to write.to(:error)
@@ -24,7 +24,7 @@ describe JSON::LD do
24
24
  t.options[:ordered] = true
25
25
  if %w(#t0068).include?(t.property('@id'))
26
26
  expect{t.run self}.to write("[DEPRECATION]").to(:error)
27
- elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #t0119 #t0120).include?(t.property('@id'))
27
+ elsif %w(#t0005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #t0119 #t0120).include?(t.property('@id'))
28
28
  expect{t.run self}.to write("beginning with '@' are reserved for future use").to(:error)
29
29
  else
30
30
  expect {t.run self}.not_to write.to(:error)
@@ -13,7 +13,6 @@ describe JSON::LD do
13
13
  end
14
14
 
15
15
  specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
- pending "Ordered version of in03" if %w(#tin03).include?(t.property('@id'))
17
16
  t.options[:ordered] = true
18
17
  expect {t.run self}.not_to write.to(:error)
19
18
  end
@@ -182,6 +182,10 @@ module Fixtures
182
182
  def positiveTest?
183
183
  property('@type').to_s.include?('Positive')
184
184
  end
185
+
186
+ def syntaxTest?
187
+ property('@type').to_s.include?('Syntax')
188
+ end
185
189
 
186
190
 
187
191
  # Execute the test
@@ -13,7 +13,7 @@ describe JSON::LD do
13
13
  expect {t.run self}.to write(/Statement .* is invalid/).to(:error)
14
14
  elsif %w(#te075).include?(t.property('@id'))
15
15
  expect {t.run self}.to write(/is invalid/).to(:error)
16
- elsif %w(#te005 #tpr34 #tpr35 #tpr36 #tpr37 #te119 #te120).include?(t.property('@id'))
16
+ elsif %w(#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120).include?(t.property('@id'))
17
17
  expect {t.run self}.to write("beginning with '@' are reserved for future use").to(:error)
18
18
  elsif %w(#te068).include?(t.property('@id'))
19
19
  expect {t.run self}.to write("[DEPRECATION]").to(:error)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-19 00:00:00.000000000 Z
11
+ date: 2020-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -424,7 +424,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
424
424
  - !ruby/object:Gem::Version
425
425
  version: '0'
426
426
  requirements: []
427
- rubygems_version: 3.1.2
427
+ rubygems_version: 3.0.6
428
428
  signing_key:
429
429
  specification_version: 4
430
430
  summary: JSON-LD reader/writer for Ruby.