json-ld 3.1.1 → 3.1.6

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.
@@ -16,6 +16,8 @@ module JSON::LD
16
16
  # @return RDF::Resource the subject of this item
17
17
  def item_to_rdf(item, graph_name: nil, &block)
18
18
  # Just return value object as Term
19
+ return unless item
20
+
19
21
  if value?(item)
20
22
  value, datatype = item.fetch('@value'), item.fetch('@type', nil)
21
23
 
@@ -76,11 +78,13 @@ module JSON::LD
76
78
  return parse_list(item['@list'], graph_name: graph_name, &block)
77
79
  end
78
80
 
79
- # Skip if '@id' is nil
80
- subject = if item.has_key?('@id')
81
- item['@id'].nil? ? nil : as_resource(item['@id'])
82
- else
83
- node
81
+ subject = case item['@id']
82
+ when nil then node
83
+ when String then as_resource(item['@id'])
84
+ when Object
85
+ # Embedded statement
86
+ # (No error checking, as this is done in expansion)
87
+ to_enum(:item_to_rdf, item['@id']).to_a.first
84
88
  end
85
89
 
86
90
  #log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
@@ -93,7 +93,7 @@ module JSON::LD
93
93
  datatype: RDF::URI,
94
94
  control: :url2,
95
95
  on: ["--context CONTEXT"],
96
- description: "Context to use when compacting.") {|arg| RDF::URI(arg)},
96
+ description: "Context to use when compacting.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))},
97
97
  RDF::CLI::Option.new(
98
98
  symbol: :embed,
99
99
  datatype: %w(@always @once @never),
@@ -107,6 +107,13 @@ module JSON::LD
107
107
  control: :checkbox,
108
108
  on: ["--[no-]explicit"],
109
109
  description: "Only include explicitly declared properties in output (false)") {|arg| arg},
110
+ RDF::CLI::Option.new(
111
+ symbol: :frame,
112
+ datatype: RDF::URI,
113
+ control: :url2,
114
+ use: :required,
115
+ on: ["--frame FRAME"],
116
+ description: "Frame to use when serializing.") {|arg| RDF::URI(arg).absolute? ? RDF::URI(arg) : StringIO.new(File.read(arg))},
110
117
  RDF::CLI::Option.new(
111
118
  symbol: :lowercaseLanguage,
112
119
  datatype: TrueClass,
@@ -137,7 +144,7 @@ module JSON::LD
137
144
  default: 'null',
138
145
  control: :select,
139
146
  on: ["--rdf-direction DIR", %w(i18n-datatype compound-literal)],
140
- description: "How to serialize literal direction (i18n-datatype compound-literal)") {|arg| RDF::URI(arg)},
147
+ description: "How to serialize literal direction (i18n-datatype compound-literal)") {|arg| arg},
141
148
  RDF::CLI::Option.new(
142
149
  symbol: :requireAll,
143
150
  datatype: TrueClass,
@@ -202,7 +209,7 @@ module JSON::LD
202
209
  end
203
210
 
204
211
  ##
205
- # Initializes the RDF-LD writer instance.
212
+ # Initializes the JSON-LD writer instance.
206
213
  #
207
214
  # @param [IO, File] output
208
215
  # the output stream
@@ -564,6 +564,7 @@ describe JSON::LD::API do
564
564
  documentUrl: "http://example.com/context")
565
565
  end
566
566
  it "uses referenced context" do
567
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
567
568
  input = ::JSON.parse %({
568
569
  "http://example.com/b": "c"
569
570
  })
@@ -56,15 +56,8 @@ describe JSON::LD::Context do
56
56
  describe "#parse" do
57
57
  context "remote" do
58
58
 
59
- it "retrieves and parses a remote context document" do
60
- JSON::LD::Context::PRELOADED.clear
61
- expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
62
- ec = subject.parse("http://example.com/context")
63
- expect(ec.provided_context).to produce("http://example.com/context", logger)
64
- end
65
-
66
59
  it "fails given a missing remote @context" do
67
- JSON::LD::Context::PRELOADED.clear
60
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
68
61
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_raise(IOError)
69
62
  expect {subject.parse("http://example.com/context")}.to raise_error(JSON::LD::JsonLdError::LoadingRemoteContextFailed, %r{http://example.com/context})
70
63
  end
@@ -116,7 +109,7 @@ describe JSON::LD::Context do
116
109
  documentUrl: "http://example.com/context",
117
110
  contentType: "text/html")
118
111
 
119
- JSON::LD::Context::PRELOADED.clear
112
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
120
113
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
121
114
  ec = subject.parse("http://example.com/context")
122
115
  expect(ec.send(:mappings)).to produce({
@@ -154,7 +147,7 @@ describe JSON::LD::Context do
154
147
  ),
155
148
  documentUrl: "http://example.com/context",
156
149
  contentType: "text/html")
157
- JSON::LD::Context::PRELOADED.clear
150
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
158
151
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
159
152
  ec = subject.parse("http://example.com/context")
160
153
  expect(ec.send(:mappings)).to produce({
@@ -170,7 +163,7 @@ describe JSON::LD::Context do
170
163
  end
171
164
 
172
165
  it "parses a referenced context at a relative URI" do
173
- JSON::LD::Context::PRELOADED.clear
166
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
174
167
  rd1 = JSON::LD::API::RemoteDocument.new(%({"@context": "context"}), base_uri: "http://example.com/c1")
175
168
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c1", anything).and_yield(rd1)
176
169
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
@@ -185,17 +178,11 @@ describe JSON::LD::Context do
185
178
 
186
179
  context "remote with local mappings" do
187
180
  let(:ctx) {["http://example.com/context", {"integer" => "xsd:integer"}]}
188
- before {JSON::LD::Context::PRELOADED.clear}
181
+ before {JSON::LD::Context.instance_variable_set(:@cache, nil)}
189
182
  it "retrieves and parses a remote context document" do
190
183
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
191
184
  subject.parse(ctx)
192
185
  end
193
-
194
- it "does not use passed context as provided_context" do
195
- expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
196
- ec = subject.parse(ctx)
197
- expect(ec.provided_context).to produce(ctx, logger)
198
- end
199
186
  end
200
187
 
201
188
  context "pre-loaded remote" do
@@ -206,7 +193,7 @@ describe JSON::LD::Context do
206
193
  )
207
194
  JSON::LD::Context.alias_preloaded("https://example.com/preloaded", "http://example.com/preloaded")
208
195
  }
209
- after(:all) {JSON::LD::Context::PRELOADED.clear}
196
+ after(:all) {JSON::LD::Context.instance_variable_set(:@cache, nil)}
210
197
 
211
198
  it "does not load referenced context" do
212
199
  expect(JSON::LD::API).not_to receive(:documentLoader).with(ctx, anything)
@@ -249,6 +236,7 @@ describe JSON::LD::Context do
249
236
  end
250
237
 
251
238
  it "merges definitions from remote contexts" do
239
+ JSON::LD::Context.instance_variable_set(:@cache, nil)
252
240
  expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
253
241
  rd2 = JSON::LD::API::RemoteDocument.new(%q({
254
242
  "@context": {
@@ -476,7 +464,7 @@ describe JSON::LD::Context do
476
464
  end
477
465
 
478
466
  context "@import" do
479
- before(:each) {JSON::LD::Context::PRELOADED.clear}
467
+ before(:each) {JSON::LD::Context.instance_variable_set(:@cache, nil)}
480
468
  it "generates an InvalidImportValue error if not a string" do
481
469
  expect {subject.parse({'@version' => 1.1, '@import' => true})}.to raise_error(JSON::LD::JsonLdError::InvalidImportValue)
482
470
  end
@@ -503,7 +491,7 @@ describe JSON::LD::Context do
503
491
  "@type as object" => {"foo" => {"@type" => {}}},
504
492
  "@type as array" => {"foo" => {"@type" => []}},
505
493
  "@type as @list" => {"foo" => {"@type" => "@list"}},
506
- "@type as @none" => {"@version": 1.1, "foo" => {"@type" => "@none"}},
494
+ "@type as @none" => {"@version" => 1.1, "foo" => {"@type" => "@none"}},
507
495
  "@type as @set" => {"foo" => {"@type" => "@set"}},
508
496
  "@container as object" => {"foo" => {"@container" => {}}},
509
497
  "@container as empty array" => {"foo" => {"@container" => []}},
@@ -642,26 +630,8 @@ describe JSON::LD::Context do
642
630
  end
643
631
  end
644
632
 
645
- describe "#merge!" do
646
- it "updates context with components from new" do
647
- c2 = JSON::LD::Context.parse({'foo' => "http://example.com/"})
648
- cm = context.merge!(c2)
649
- expect(cm).to equal context
650
- expect(cm).not_to equal c2
651
- expect(cm.term_definitions).to eq c2.term_definitions
652
- end
653
- end
654
-
655
633
  describe "#serialize" do
656
- before {JSON::LD::Context::PRELOADED.clear}
657
- it "context document" do
658
- expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
659
- ec = subject.parse("http://example.com/context")
660
- expect(ec.serialize).to produce({
661
- "@context" => "http://example.com/context"
662
- }, logger)
663
- end
664
-
634
+ before {JSON::LD::Context.instance_variable_set(:@cache, nil)}
665
635
  it "context hash" do
666
636
  ctx = {"foo" => "http://example.com/"}
667
637
 
@@ -693,7 +663,7 @@ describe JSON::LD::Context do
693
663
 
694
664
  it "term mappings" do
695
665
  c = subject.
696
- parse({'foo' => "http://example.com/"}).send(:clear_provided_context)
666
+ parse({'foo' => "http://example.com/"})
697
667
  expect(c.serialize).to produce({
698
668
  "@context" => {
699
669
  "foo" => "http://example.com/"
@@ -705,7 +675,7 @@ describe JSON::LD::Context do
705
675
  it "@context" do
706
676
  expect(subject.parse({
707
677
  "foo" => {"@id" => "http://example.com/", "@context" => {"bar" => "http://example.com/baz"}}
708
- }).send(:clear_provided_context).
678
+ }).
709
679
  serialize).to produce({
710
680
  "@context" => {
711
681
  "foo" => {
@@ -721,7 +691,6 @@ describe JSON::LD::Context do
721
691
  'xsd' => "http://www.w3.org/2001/XMLSchema#",
722
692
  'homepage' => {'@id' => RDF::Vocab::FOAF.homepage.to_s, '@type' => '@id'}
723
693
  }).
724
- send(:clear_provided_context).
725
694
  serialize).to produce({
726
695
  "@context" => {
727
696
  "xsd" => RDF::XSD.to_uri.to_s,
@@ -734,7 +703,6 @@ describe JSON::LD::Context do
734
703
  expect(subject.parse({
735
704
  'knows' => {'@id' => RDF::Vocab::FOAF.knows.to_s, '@container' => '@list'}
736
705
  }).
737
- send(:clear_provided_context).
738
706
  serialize).to produce({
739
707
  "@context" => {
740
708
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"}
@@ -746,7 +714,6 @@ describe JSON::LD::Context do
746
714
  expect(subject.parse({
747
715
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set"}
748
716
  }).
749
- send(:clear_provided_context).
750
717
  serialize).to produce({
751
718
  "@context" => {
752
719
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@set"}
@@ -758,7 +725,6 @@ describe JSON::LD::Context do
758
725
  expect(subject.parse({
759
726
  "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en"}
760
727
  }).
761
- send(:clear_provided_context).
762
728
  serialize).to produce({
763
729
  "@context" => {
764
730
  "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "en"}
@@ -771,7 +737,6 @@ describe JSON::LD::Context do
771
737
  "@language" => 'en',
772
738
  "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => 'en'}
773
739
  }).
774
- send(:clear_provided_context).
775
740
  serialize).to produce({
776
741
  "@context" => {
777
742
  "@language" => 'en',
@@ -785,7 +750,6 @@ describe JSON::LD::Context do
785
750
  "@language" => 'en',
786
751
  "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => "de"}
787
752
  }).
788
- send(:clear_provided_context).
789
753
  serialize).to produce({
790
754
  "@context" => {
791
755
  "@language" => 'en',
@@ -799,7 +763,6 @@ describe JSON::LD::Context do
799
763
  "@language" => 'en',
800
764
  "name" => {"@id" => RDF::Vocab::FOAF.name.to_s, "@language" => nil}
801
765
  }).
802
- send(:clear_provided_context).
803
766
  serialize).to produce({
804
767
  "@context" => {
805
768
  "@language" => 'en',
@@ -812,7 +775,6 @@ describe JSON::LD::Context do
812
775
  expect(subject.parse({
813
776
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list"}
814
777
  }).
815
- send(:clear_provided_context).
816
778
  serialize).to produce({
817
779
  "@context" => {
818
780
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list"}
@@ -824,7 +786,6 @@ describe JSON::LD::Context do
824
786
  expect(subject.parse({
825
787
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set"}
826
788
  }).
827
- send(:clear_provided_context).
828
789
  serialize).to produce({
829
790
  "@context" => {
830
791
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set"}
@@ -836,7 +797,6 @@ describe JSON::LD::Context do
836
797
  expect(subject.parse({
837
798
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"}
838
799
  }).
839
- send(:clear_provided_context).
840
800
  serialize).to produce({
841
801
  "@context" => {
842
802
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"}
@@ -851,7 +811,6 @@ describe JSON::LD::Context do
851
811
  "@container" => "@list"
852
812
  }
853
813
  }).
854
- send(:clear_provided_context).
855
814
  serialize).to produce({
856
815
  "@context" => {
857
816
  "foaf" => RDF::Vocab::FOAF.to_uri.to_s,
@@ -867,7 +826,6 @@ describe JSON::LD::Context do
867
826
  "id" => "@id",
868
827
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"}
869
828
  }).
870
- send(:clear_provided_context).
871
829
  serialize).to produce({
872
830
  "@context" => {
873
831
  "id" => "@id",
@@ -884,7 +842,6 @@ describe JSON::LD::Context do
884
842
  "@type" => "@id"
885
843
  }
886
844
  }).
887
- send(:clear_provided_context).
888
845
  serialize).to produce({
889
846
  "@context" => {
890
847
  "foaf" => RDF::Vocab::FOAF.to_uri.to_s,
@@ -902,7 +859,6 @@ describe JSON::LD::Context do
902
859
  "type" => "@type",
903
860
  "foaf:homepage" => {"@type" => "@id"}
904
861
  }).
905
- send(:clear_provided_context).
906
862
  serialize).to produce({
907
863
  "@context" => {
908
864
  "foaf" => RDF::Vocab::FOAF.to_uri.to_s,
@@ -917,7 +873,6 @@ describe JSON::LD::Context do
917
873
  "container" => "@container",
918
874
  "knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@container" => "@list"}
919
875
  }).
920
- send(:clear_provided_context).
921
876
  serialize).to produce({
922
877
  "@context" => {
923
878
  "container" => "@container",
@@ -931,7 +886,6 @@ describe JSON::LD::Context do
931
886
  "ex" => 'http://example.org/',
932
887
  "term" => {"@id" => "ex:term", "@type" => "ex:datatype"}
933
888
  }).
934
- send(:clear_provided_context).
935
889
  serialize).to produce({
936
890
  "@context" => {
937
891
  "ex" => 'http://example.org/',
@@ -945,7 +899,6 @@ describe JSON::LD::Context do
945
899
  "@vocab" => 'http://example.org/',
946
900
  "term" => {"@id" => "http://example.org/term", "@type" => "datatype"}
947
901
  }).
948
- send(:clear_provided_context).
949
902
  serialize).to produce({
950
903
  "@context" => {
951
904
  "@vocab" => 'http://example.org/',
@@ -954,11 +907,13 @@ describe JSON::LD::Context do
954
907
  }, logger)
955
908
  end
956
909
 
957
- context "extra keys or values" do
910
+ context "invalid term definitions" do
958
911
  {
959
- "extra key" => {
960
- input: {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}},
961
- result: {"@context" => {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}}}
912
+ "empty term": {
913
+ input: {"" => "http://blank-term/"}
914
+ },
915
+ "extra key": {
916
+ input: {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}}
962
917
  }
963
918
  }.each do |title, params|
964
919
  it title do
@@ -975,7 +930,6 @@ describe JSON::LD::Context do
975
930
  '@base' => 'http://base/',
976
931
  '@vocab' => 'http://vocab/',
977
932
  'ex' => 'http://example.org/',
978
- '' => 'http://empty/',
979
933
  '_' => 'http://underscore/'
980
934
  })
981
935
  }
@@ -1039,7 +993,6 @@ describe JSON::LD::Context do
1039
993
  '@base' => 'http://base/base',
1040
994
  '@vocab' => 'http://vocab/',
1041
995
  'ex' => 'http://example.org/',
1042
- '' => 'http://empty/',
1043
996
  '_' => 'http://underscore/'
1044
997
  })
1045
998
  }
@@ -1119,7 +1072,6 @@ describe JSON::LD::Context do
1119
1072
  "unmapped" => ["foo", RDF::URI("http://vocab/foo")],
1120
1073
  "relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")],
1121
1074
  "dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")],
1122
- "empty term" => ["", RDF::URI("http://empty/")],
1123
1075
  "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
1124
1076
  "absolute IRI looking like a compact IRI" =>
1125
1077
  ["foo:bar", RDF::URI("foo:bar")],
@@ -1138,7 +1090,6 @@ describe JSON::LD::Context do
1138
1090
  '@base' => 'http://base/base',
1139
1091
  '@vocab' => '',
1140
1092
  'ex' => 'http://example.org/',
1141
- '' => 'http://empty/',
1142
1093
  '_' => 'http://underscore/'
1143
1094
  })
1144
1095
  }
@@ -1153,7 +1104,6 @@ describe JSON::LD::Context do
1153
1104
  "unmapped" => ["foo", RDF::URI("http://base/basefoo")],
1154
1105
  "relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")],
1155
1106
  "dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")],
1156
- "empty term" => ["", RDF::URI("http://empty/")],
1157
1107
  "another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
1158
1108
  "absolute IRI looking like a compact IRI" =>
1159
1109
  ["foo:bar", RDF::URI("foo:bar")],
@@ -1183,7 +1133,6 @@ describe JSON::LD::Context do
1183
1133
  '@base' => 'http://base/',
1184
1134
  "xsd" => "http://www.w3.org/2001/XMLSchema#",
1185
1135
  'ex' => 'http://example.org/',
1186
- '' => 'http://empty/',
1187
1136
  '_' => 'http://underscore/',
1188
1137
  'rex' => {'@reverse' => "ex"},
1189
1138
  'lex' => {'@id' => 'ex', '@language' => 'en'},
@@ -1258,7 +1207,7 @@ describe JSON::LD::Context do
1258
1207
  it "does not use @vocab if it would collide with a term" do
1259
1208
  subject.set_mapping("name", "http://xmlns.com/foaf/0.1/name")
1260
1209
  subject.set_mapping("ex", nil)
1261
- expect(subject.compact_iri("http://example.org/name", position: :predicate)).
1210
+ expect(subject.compact_iri("http://example.org/name", vocab: true)).
1262
1211
  not_to produce("name", logger)
1263
1212
  end
1264
1213
 
@@ -1390,7 +1339,6 @@ describe JSON::LD::Context do
1390
1339
  "absolute IRI" => ["http://example.com/", "http://example.com/"],
1391
1340
  "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
1392
1341
  "keyword" => ["@type", "@type"],
1393
- "empty" => [":suffix", "http://empty/suffix"],
1394
1342
  "unmapped" => ["foo", "foo"],
1395
1343
  "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
1396
1344
  "relative" => ["foo/bar", "http://base/foo/bar"],
@@ -1412,7 +1360,6 @@ describe JSON::LD::Context do
1412
1360
  "absolute IRI" => ["http://example.com/", "http://example.com/"],
1413
1361
  "prefix:suffix" => ["suffix", "http://example.org/suffix"],
1414
1362
  "keyword" => ["@type", "@type"],
1415
- "empty" => [":suffix", "http://empty/suffix"],
1416
1363
  "unmapped" => ["foo", "foo"],
1417
1364
  "bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
1418
1365
  "relative" => ["http://base/foo/bar", "http://base/foo/bar"],
@@ -1543,7 +1490,7 @@ describe JSON::LD::Context do
1543
1490
  })
1544
1491
  end
1545
1492
  it "Compact @id that is a property IRI when @container is @list" do
1546
- expect(ctx.compact_iri("http://example.org/ns#property", position: :subject)).
1493
+ expect(ctx.compact_iri("http://example.org/ns#property", vocab: false)).
1547
1494
  to produce("ex:property", logger)
1548
1495
  end
1549
1496
  end
@@ -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
@@ -3356,6 +3376,254 @@ describe JSON::LD::API do
3356
3376
  end
3357
3377
  end
3358
3378
 
3379
+ context "JSON-LD*" do
3380
+ {
3381
+ "node with embedded subject without rdfstar option": {
3382
+ input: %({
3383
+ "@id": {
3384
+ "@id": "ex:rei",
3385
+ "ex:prop": "value"
3386
+ },
3387
+ "ex:prop": "value2"
3388
+ }),
3389
+ exception: JSON::LD::JsonLdError::InvalidIdValue
3390
+ },
3391
+ }.each do |title, params|
3392
+ it(title) {run_expand params}
3393
+ end
3394
+
3395
+ {
3396
+ "node with embedded subject having no @id": {
3397
+ input: %({
3398
+ "@id": {
3399
+ "ex:prop": "value"
3400
+ },
3401
+ "ex:prop": "value2"
3402
+ }),
3403
+ output: %([{
3404
+ "@id": {
3405
+ "ex:prop": [{"@value": "value"}]
3406
+ },
3407
+ "ex:prop": [{"@value": "value2"}]
3408
+ }])
3409
+ },
3410
+ "node with embedded subject having IRI @id": {
3411
+ input: %({
3412
+ "@id": {
3413
+ "@id": "ex:rei",
3414
+ "ex:prop": "value"
3415
+ },
3416
+ "ex:prop": "value2"
3417
+ }),
3418
+ output: %([{
3419
+ "@id": {
3420
+ "@id": "ex:rei",
3421
+ "ex:prop": [{"@value": "value"}]
3422
+ },
3423
+ "ex:prop": [{"@value": "value2"}]
3424
+ }])
3425
+ },
3426
+ "node with embedded subject having BNode @id": {
3427
+ input: %({
3428
+ "@id": {
3429
+ "@id": "_:rei",
3430
+ "ex:prop": "value"
3431
+ },
3432
+ "ex:prop": "value2"
3433
+ }),
3434
+ output: %([{
3435
+ "@id": {
3436
+ "@id": "_:rei",
3437
+ "ex:prop": [{"@value": "value"}]
3438
+ },
3439
+ "ex:prop": [{"@value": "value2"}]
3440
+ }])
3441
+ },
3442
+ "node with embedded subject having a type": {
3443
+ input: %({
3444
+ "@id": {
3445
+ "@id": "ex:rei",
3446
+ "@type": "ex:Type"
3447
+ },
3448
+ "ex:prop": "value2"
3449
+ }),
3450
+ output: %([{
3451
+ "@id": {
3452
+ "@id": "ex:rei",
3453
+ "@type": ["ex:Type"]
3454
+ },
3455
+ "ex:prop": [{"@value": "value2"}]
3456
+ }])
3457
+ },
3458
+ "node with embedded subject having an IRI value": {
3459
+ input: %({
3460
+ "@id": {
3461
+ "@id": "ex:rei",
3462
+ "ex:prop": {"@id": "ex:value"}
3463
+ },
3464
+ "ex:prop": "value2"
3465
+ }),
3466
+ output: %([{
3467
+ "@id": {
3468
+ "@id": "ex:rei",
3469
+ "ex:prop": [{"@id": "ex:value"}]
3470
+ },
3471
+ "ex:prop": [{"@value": "value2"}]
3472
+ }])
3473
+ },
3474
+ "node with embedded subject having an BNode value": {
3475
+ input: %({
3476
+ "@id": {
3477
+ "@id": "ex:rei",
3478
+ "ex:prop": {"@id": "_:value"}
3479
+ },
3480
+ "ex:prop": "value2"
3481
+ }),
3482
+ output: %([{
3483
+ "@id": {
3484
+ "@id": "ex:rei",
3485
+ "ex:prop": [{"@id": "_:value"}]
3486
+ },
3487
+ "ex:prop": [{"@value": "value2"}]
3488
+ }])
3489
+ },
3490
+ "node with recursive embedded subject": {
3491
+ input: %({
3492
+ "@id": {
3493
+ "@id": {
3494
+ "@id": "ex:rei",
3495
+ "ex:prop": "value3"
3496
+ },
3497
+ "ex:prop": "value"
3498
+ },
3499
+ "ex:prop": "value2"
3500
+ }),
3501
+ output: %([{
3502
+ "@id": {
3503
+ "@id": {
3504
+ "@id": "ex:rei",
3505
+ "ex:prop": [{"@value": "value3"}]
3506
+ },
3507
+ "ex:prop": [{"@value": "value"}]
3508
+ },
3509
+ "ex:prop": [{"@value": "value2"}]
3510
+ }])
3511
+ },
3512
+ "illegal node with subject having no property": {
3513
+ input: %({
3514
+ "@id": {
3515
+ "@id": "ex:rei"
3516
+ },
3517
+ "ex:prop": "value3"
3518
+ }),
3519
+ exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3520
+ },
3521
+ "illegal node with subject having multiple properties": {
3522
+ input: %({
3523
+ "@id": {
3524
+ "@id": "ex:rei",
3525
+ "ex:prop": ["value1", "value2"]
3526
+ },
3527
+ "ex:prop": "value3"
3528
+ }),
3529
+ exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3530
+ },
3531
+ "illegal node with subject having multiple types": {
3532
+ input: %({
3533
+ "@id": {
3534
+ "@id": "ex:rei",
3535
+ "@type": ["ex:Type1", "ex:Type2"]
3536
+ },
3537
+ "ex:prop": "value3"
3538
+ }),
3539
+ exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3540
+ },
3541
+ "illegal node with subject having type and property": {
3542
+ input: %({
3543
+ "@id": {
3544
+ "@id": "ex:rei",
3545
+ "@type": "ex:Type",
3546
+ "ex:prop": "value"
3547
+ },
3548
+ "ex:prop": "value2"
3549
+ }),
3550
+ exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3551
+ },
3552
+ "node with embedded object": {
3553
+ input: %({
3554
+ "@id": "ex:subj",
3555
+ "ex:value": {
3556
+ "@id": {
3557
+ "@id": "ex:rei",
3558
+ "ex:prop": "value"
3559
+ }
3560
+ }
3561
+ }),
3562
+ output: %([{
3563
+ "@id": "ex:subj",
3564
+ "ex:value": [{
3565
+ "@id": {
3566
+ "@id": "ex:rei",
3567
+ "ex:prop": [{"@value": "value"}]
3568
+ }
3569
+ }]
3570
+ }])
3571
+ },
3572
+ "illegal node with embedded object having properties": {
3573
+ input: %({
3574
+ "@id": "ex:subj",
3575
+ "ex:value": {
3576
+ "@id": {
3577
+ "@id": "ex:rei",
3578
+ "ex:prop": "value"
3579
+ },
3580
+ "ex:prop": "value2"
3581
+ }
3582
+ }),
3583
+ output: %([{
3584
+ "@id": "ex:subj",
3585
+ "ex:value": [{
3586
+ "@id": {
3587
+ "@id": "ex:rei",
3588
+ "ex:prop": [{"@value": "value"}]
3589
+ },
3590
+ "ex:prop": [{"@value": "value2"}]
3591
+ }]
3592
+ }])
3593
+ },
3594
+ "node with recursive embedded object": {
3595
+ input: %({
3596
+ "@id": "ex:subj",
3597
+ "ex:value": {
3598
+ "@id": {
3599
+ "@id": {
3600
+ "@id": "ex:rei",
3601
+ "ex:prop": "value3"
3602
+ },
3603
+ "ex:prop": "value"
3604
+ },
3605
+ "ex:prop": "value2"
3606
+ }
3607
+ }),
3608
+ output: %([{
3609
+ "@id": "ex:subj",
3610
+ "ex:value": [{
3611
+ "@id": {
3612
+ "@id": {
3613
+ "@id": "ex:rei",
3614
+ "ex:prop": [{"@value": "value3"}]
3615
+ },
3616
+ "ex:prop":[{"@value": "value"}]
3617
+ },
3618
+ "ex:prop": [{"@value": "value2"}]
3619
+ }]
3620
+ }])
3621
+ },
3622
+ }.each do |title, params|
3623
+ it(title) {run_expand params.merge(rdfstar: true)}
3624
+ end
3625
+ end
3626
+
3359
3627
  begin
3360
3628
  require 'nokogiri'
3361
3629
  rescue LoadError
@@ -3366,7 +3634,7 @@ describe JSON::LD::API do
3366
3634
  %w(Nokogiri REXML).each do |impl|
3367
3635
  next unless Module.constants.map(&:to_s).include?(impl)
3368
3636
  context impl do
3369
- before(:all) {@library = impl.downcase.to_s.to_sym}
3637
+ let(:library) {impl.downcase.to_s.to_sym}
3370
3638
 
3371
3639
  {
3372
3640
  "Expands embedded JSON-LD script element": {
@@ -3505,9 +3773,9 @@ describe JSON::LD::API do
3505
3773
  ]),
3506
3774
  extractAllScripts: true
3507
3775
  },
3508
- "Expands as empty with no script element": {
3776
+ "Errors no script element": {
3509
3777
  input: %(<html><head></head></html>),
3510
- output: %([])
3778
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3511
3779
  },
3512
3780
  "Expands as empty with no script element and extractAllScripts": {
3513
3781
  input: %(<html><head></head></html>),
@@ -3619,7 +3887,7 @@ describe JSON::LD::API do
3619
3887
  </head>
3620
3888
  </html>),
3621
3889
  base: "http://example.org/doc#third",
3622
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3890
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3623
3891
  },
3624
3892
  "Errors if targeted element is not a script element": {
3625
3893
  input: %(
@@ -3636,7 +3904,7 @@ describe JSON::LD::API do
3636
3904
  </head>
3637
3905
  </html>),
3638
3906
  base: "http://example.org/doc#first",
3639
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3907
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3640
3908
  },
3641
3909
  "Errors if targeted element does not have type application/ld+json": {
3642
3910
  input: %(
@@ -3653,7 +3921,7 @@ describe JSON::LD::API do
3653
3921
  </head>
3654
3922
  </html>),
3655
3923
  base: "http://example.org/doc#first",
3656
- exception: JSON::LD::JsonLdError::InvalidScriptElement
3924
+ exception: JSON::LD::JsonLdError::LoadingDocumentFailed
3657
3925
  },
3658
3926
  "Errors if uncommented script text contains comment": {
3659
3927
  input: %(
@@ -3722,10 +3990,10 @@ describe JSON::LD::API do
3722
3990
  },
3723
3991
  }.each do |title, params|
3724
3992
  it(title) do
3725
- skip "rexml" if params[:not] == @library
3726
- params[:input] = StringIO.new(params[:input])
3993
+ skip "rexml" if params[:not] == library
3994
+ params = params.merge(input: StringIO.new(params[:input]))
3727
3995
  params[:input].send(:define_singleton_method, :content_type) {"text/html"}
3728
- run_expand params.merge(validate: true, library: @library)
3996
+ run_expand params.merge(validate: true, library: library)
3729
3997
  end
3730
3998
  end
3731
3999
  end