json-ld 3.1.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.