json-ld 2.2.1 → 3.0.0
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 +5 -5
- data/README.md +55 -55
- data/VERSION +1 -1
- data/lib/json/ld.rb +4 -2
- data/lib/json/ld/api.rb +49 -59
- data/lib/json/ld/compact.rb +60 -56
- data/lib/json/ld/context.rb +52 -40
- data/lib/json/ld/expand.rb +53 -61
- data/lib/json/ld/extensions.rb +31 -16
- data/lib/json/ld/flatten.rb +99 -90
- data/lib/json/ld/format.rb +2 -2
- data/lib/json/ld/frame.rb +47 -30
- data/lib/json/ld/from_rdf.rb +31 -23
- data/lib/json/ld/resource.rb +1 -1
- data/lib/json/ld/to_rdf.rb +4 -2
- data/lib/json/ld/utils.rb +25 -35
- data/lib/json/ld/writer.rb +25 -1
- data/spec/api_spec.rb +1 -0
- data/spec/compact_spec.rb +536 -31
- data/spec/context_spec.rb +109 -43
- data/spec/expand_spec.rb +413 -18
- data/spec/flatten_spec.rb +107 -27
- data/spec/frame_spec.rb +255 -34
- data/spec/from_rdf_spec.rb +102 -3
- data/spec/streaming_writer_spec.rb +8 -9
- data/spec/suite_compact_spec.rb +2 -2
- data/spec/suite_expand_spec.rb +2 -2
- data/spec/suite_flatten_spec.rb +2 -2
- data/spec/suite_frame_spec.rb +2 -2
- data/spec/suite_from_rdf_spec.rb +2 -3
- data/spec/suite_helper.rb +57 -61
- data/spec/suite_remote_doc_spec.rb +2 -2
- data/spec/suite_to_rdf_spec.rb +4 -4
- data/spec/to_rdf_spec.rb +88 -1
- data/spec/writer_spec.rb +5 -6
- metadata +5 -7
- data/spec/suite_error_spec.rb +0 -16
data/spec/context_spec.rb
CHANGED
@@ -55,12 +55,14 @@ describe JSON::LD::Context do
|
|
55
55
|
context "remote" do
|
56
56
|
|
57
57
|
it "retrieves and parses a remote context document" do
|
58
|
+
JSON::LD::Context::PRELOADED.clear
|
58
59
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
59
60
|
ec = subject.parse("http://example.com/context")
|
60
61
|
expect(ec.provided_context).to produce("http://example.com/context", logger)
|
61
62
|
end
|
62
63
|
|
63
64
|
it "fails given a missing remote @context" do
|
65
|
+
JSON::LD::Context::PRELOADED.clear
|
64
66
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_raise(IOError)
|
65
67
|
expect {subject.parse("http://example.com/context")}.to raise_error(JSON::LD::JsonLdError::LoadingRemoteContextFailed, %r{http://example.com/context})
|
66
68
|
end
|
@@ -81,6 +83,7 @@ describe JSON::LD::Context do
|
|
81
83
|
end
|
82
84
|
|
83
85
|
it "parses a referenced context at a relative URI" do
|
86
|
+
JSON::LD::Context::PRELOADED.clear
|
84
87
|
rd1 = JSON::LD::API::RemoteDocument.new("http://example.com/c1", %({"@context": "context"}))
|
85
88
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c1", anything).and_yield(rd1)
|
86
89
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
@@ -95,6 +98,7 @@ describe JSON::LD::Context do
|
|
95
98
|
|
96
99
|
context "remote with local mappings" do
|
97
100
|
let(:ctx) {["http://example.com/context", {"integer" => "xsd:integer"}]}
|
101
|
+
before {JSON::LD::Context::PRELOADED.clear}
|
98
102
|
it "retrieves and parses a remote context document" do
|
99
103
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
100
104
|
subject.parse(ctx)
|
@@ -375,16 +379,6 @@ describe JSON::LD::Context do
|
|
375
379
|
end
|
376
380
|
|
377
381
|
describe "#processingMode" do
|
378
|
-
it "sets to json-ld-1.0 if not specified" do
|
379
|
-
[
|
380
|
-
%({}),
|
381
|
-
%([{}]),
|
382
|
-
].each do |str|
|
383
|
-
ctx = JSON::LD::Context.parse(::JSON.parse(str))
|
384
|
-
expect(ctx.processingMode).to eql "json-ld-1.0"
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
382
|
it "sets to json-ld-1.1 if @version: 1.1" do
|
389
383
|
[
|
390
384
|
%({"@version": 1.1}),
|
@@ -410,8 +404,8 @@ describe JSON::LD::Context do
|
|
410
404
|
expect {JSON::LD::Context.parse({"@version" => 1.1}, processingMode: "json-ld-1.0")}.to raise_error(JSON::LD::JsonLdError::ProcessingModeConflict)
|
411
405
|
end
|
412
406
|
|
413
|
-
it "
|
414
|
-
expect {JSON::LD::Context.parse([{}, {"@version" => 1.1}])}.
|
407
|
+
it "does not raise ProcessingModeConflict nested context is different from starting context" do
|
408
|
+
expect {JSON::LD::Context.parse([{}, {"@version" => 1.1}])}.not_to raise_error
|
415
409
|
end
|
416
410
|
end
|
417
411
|
|
@@ -436,6 +430,7 @@ describe JSON::LD::Context do
|
|
436
430
|
end
|
437
431
|
|
438
432
|
describe "#serialize" do
|
433
|
+
before {JSON::LD::Context::PRELOADED.clear}
|
439
434
|
it "context document" do
|
440
435
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
441
436
|
ec = subject.parse("http://example.com/context")
|
@@ -764,7 +759,7 @@ describe JSON::LD::Context do
|
|
764
759
|
describe "#expand_iri" do
|
765
760
|
subject {
|
766
761
|
context.parse({
|
767
|
-
'@base' => 'http://base/',
|
762
|
+
'@base' => 'http://base/base',
|
768
763
|
'@vocab' => 'http://vocab/',
|
769
764
|
'ex' => 'http://example.org/',
|
770
765
|
'' => 'http://empty/',
|
@@ -794,6 +789,8 @@ describe JSON::LD::Context do
|
|
794
789
|
"keyword" => ["@type", "@type"],
|
795
790
|
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
796
791
|
"unmapped" => ["foo", RDF::URI("foo")],
|
792
|
+
"relative" => ["foo/bar", RDF::URI("foo/bar")],
|
793
|
+
"dotseg" => ["../foo/bar", RDF::URI("../foo/bar")],
|
797
794
|
"empty term" => ["", RDF::URI("")],
|
798
795
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
799
796
|
"absolute IRI looking like a curie" =>
|
@@ -815,7 +812,9 @@ describe JSON::LD::Context do
|
|
815
812
|
"keyword" => ["@type", "@type"],
|
816
813
|
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
817
814
|
"unmapped" => ["foo", RDF::URI("http://base/foo")],
|
818
|
-
"
|
815
|
+
"relative" => ["foo/bar", RDF::URI("http://base/foo/bar")],
|
816
|
+
"dotseg" => ["../foo/bar", RDF::URI("http://base/foo/bar")],
|
817
|
+
"empty term" => ["", RDF::URI("http://base/base")],
|
819
818
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
820
819
|
"absolute IRI looking like a curie" =>
|
821
820
|
["foo:bar", RDF::URI("foo:bar")],
|
@@ -836,6 +835,8 @@ describe JSON::LD::Context do
|
|
836
835
|
"keyword" => ["@type", "@type"],
|
837
836
|
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
838
837
|
"unmapped" => ["foo", RDF::URI("http://vocab/foo")],
|
838
|
+
"relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")],
|
839
|
+
"dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")],
|
839
840
|
"empty term" => ["", RDF::URI("http://empty/")],
|
840
841
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
841
842
|
"absolute IRI looking like a curie" =>
|
@@ -847,6 +848,39 @@ describe JSON::LD::Context do
|
|
847
848
|
expect(subject.expand_iri(input, vocab: true)).to produce(result, logger)
|
848
849
|
end
|
849
850
|
end
|
851
|
+
|
852
|
+
context "set to ''" do
|
853
|
+
subject {
|
854
|
+
context.parse({
|
855
|
+
'@base' => 'http://base/base',
|
856
|
+
'@vocab' => '',
|
857
|
+
'ex' => 'http://example.org/',
|
858
|
+
'' => 'http://empty/',
|
859
|
+
'_' => 'http://underscore/'
|
860
|
+
})
|
861
|
+
}
|
862
|
+
|
863
|
+
{
|
864
|
+
"absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")],
|
865
|
+
"term" => ["ex", RDF::URI("http://example.org/")],
|
866
|
+
"prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")],
|
867
|
+
"keyword" => ["@type", "@type"],
|
868
|
+
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
869
|
+
"unmapped" => ["foo", RDF::URI("http://base/basefoo")],
|
870
|
+
"relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")],
|
871
|
+
"dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")],
|
872
|
+
"empty term" => ["", RDF::URI("http://empty/")],
|
873
|
+
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
874
|
+
"absolute IRI looking like a curie" =>
|
875
|
+
["foo:bar", RDF::URI("foo:bar")],
|
876
|
+
"bnode" => ["_:t0", RDF::Node("t0")],
|
877
|
+
"_" => ["_", RDF::URI("http://underscore/")],
|
878
|
+
}.each do |title, (input, result)|
|
879
|
+
it title do
|
880
|
+
expect(subject.expand_iri(input, vocab: true)).to produce(result, logger)
|
881
|
+
end
|
882
|
+
end
|
883
|
+
end
|
850
884
|
end
|
851
885
|
end
|
852
886
|
end
|
@@ -926,6 +960,28 @@ describe JSON::LD::Context do
|
|
926
960
|
expect(subject.compact_iri("http://example.org/name", position: :predicate)).
|
927
961
|
not_to produce("name", logger)
|
928
962
|
end
|
963
|
+
|
964
|
+
context "with @vocab: relative" do
|
965
|
+
before(:each) {
|
966
|
+
subject.vocab = ""
|
967
|
+
subject.base = 'http://base/base'
|
968
|
+
}
|
969
|
+
|
970
|
+
{
|
971
|
+
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
972
|
+
"prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
|
973
|
+
"keyword" => ["@type", "@type"],
|
974
|
+
"empty" => [":suffix", "http://empty/suffix"],
|
975
|
+
"unmapped" => ["foo", "foo"],
|
976
|
+
"bnode" => ["_:a", RDF::Node("a")],
|
977
|
+
"relative" => ["foo/bar", "http://base/foo/bar"],
|
978
|
+
"odd CURIE" => ["experts", "http://example.org/perts"]
|
979
|
+
}.each do |title, (result, input)|
|
980
|
+
it title do
|
981
|
+
expect(subject.compact_iri(input, vocab: true)).to produce(result, logger)
|
982
|
+
end
|
983
|
+
end
|
984
|
+
end
|
929
985
|
end
|
930
986
|
|
931
987
|
context "with value" do
|
@@ -939,47 +995,57 @@ describe JSON::LD::Context do
|
|
939
995
|
"double" => {"@id" => "http://example.com/double", "@type" => "xsd:double"},
|
940
996
|
"date" => {"@id" => "http://example.com/date", "@type" => "xsd:date"},
|
941
997
|
"id" => {"@id" => "http://example.com/id", "@type" => "@id"},
|
942
|
-
|
943
|
-
|
944
|
-
"
|
945
|
-
"
|
946
|
-
"
|
947
|
-
"
|
948
|
-
"
|
949
|
-
"
|
950
|
-
"
|
951
|
-
"
|
952
|
-
|
953
|
-
"
|
954
|
-
"
|
955
|
-
|
956
|
-
"
|
998
|
+
'graph' => {'@id' => 'http://example.com/graph', '@container' => '@graph'},
|
999
|
+
|
1000
|
+
"list_plain" => {"@id" => "http://example.com/plain", "@container" => "@list"},
|
1001
|
+
"list_lang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@list"},
|
1002
|
+
"list_bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@list"},
|
1003
|
+
"list_integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@list"},
|
1004
|
+
"list_double" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@list"},
|
1005
|
+
"list_date" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@list"},
|
1006
|
+
"list_id" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@list"},
|
1007
|
+
"list_graph" => {"@id" => "http://example.com/graph", "@type" => "@id", "@container" => "@list"},
|
1008
|
+
|
1009
|
+
"set_plain" => {"@id" => "http://example.com/plain", "@container" => "@set"},
|
1010
|
+
"set_lang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@set"},
|
1011
|
+
"set_bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@set"},
|
1012
|
+
"set_integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@set"},
|
1013
|
+
"set_double" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@set"},
|
1014
|
+
"set_date" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@set"},
|
1015
|
+
"set_id" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@set"},
|
1016
|
+
'set_graph' => {'@id' => 'http://example.com/graph', '@container' => ['@graph', '@set']},
|
1017
|
+
|
1018
|
+
"map_lang" => {"@id" => "http://example.com/lang", "@container" => "@language"},
|
1019
|
+
|
1020
|
+
"set_map_lang" => {"@id" => "http://example.com/lang", "@container" => ["@language", "@set"]},
|
957
1021
|
})
|
958
1022
|
logger.clear
|
959
1023
|
c
|
960
1024
|
end
|
961
1025
|
|
1026
|
+
# Prefered sets and maps over non sets or maps
|
962
1027
|
{
|
963
|
-
"
|
964
|
-
"
|
965
|
-
"
|
966
|
-
"
|
967
|
-
"
|
968
|
-
"
|
1028
|
+
"set_plain" => [{"@value" => "foo"}],
|
1029
|
+
"map_lang" => [{"@value" => "en", "@language" => "en"}],
|
1030
|
+
"set_bool" => [{"@value" => "true", "@type" => "http://www.w3.org/2001/XMLSchema#boolean"}],
|
1031
|
+
"set_integer" => [{"@value" => "1", "@type" => "http://www.w3.org/2001/XMLSchema#integer"}],
|
1032
|
+
"set_id" => [{"@id" => "http://example.org/id"}],
|
1033
|
+
"graph" => [{"@graph" => [{"@id" => "http://example.org/id"}]}],
|
969
1034
|
}.each do |prop, values|
|
970
1035
|
context "uses #{prop}" do
|
971
1036
|
values.each do |value|
|
972
1037
|
it "for #{value.inspect}" do
|
973
|
-
expect(ctx.compact_iri("http://example.com/#{prop.sub(
|
1038
|
+
expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: value, vocab: true)).
|
974
1039
|
to produce(prop, logger)
|
975
1040
|
end
|
976
1041
|
end
|
977
1042
|
end
|
978
1043
|
end
|
979
1044
|
|
1045
|
+
# @language and @type with @list
|
980
1046
|
context "for @list" do
|
981
1047
|
{
|
982
|
-
"
|
1048
|
+
"list_plain" => [
|
983
1049
|
[{"@value" => "foo"}],
|
984
1050
|
[{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => "baz"}],
|
985
1051
|
[{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}],
|
@@ -990,16 +1056,16 @@ describe JSON::LD::Context do
|
|
990
1056
|
[{"@value" => true}], [{"@value" => false}],
|
991
1057
|
[{"@value" => 1}], [{"@value" => 1.1}],
|
992
1058
|
],
|
993
|
-
"
|
994
|
-
"
|
995
|
-
"
|
996
|
-
"
|
997
|
-
"
|
1059
|
+
"list_lang" => [[{"@value" => "en", "@language" => "en"}]],
|
1060
|
+
"list_bool" => [[{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}]],
|
1061
|
+
"list_integer" => [[{"@value" => "1", "@type" => RDF::XSD.integer.to_s}]],
|
1062
|
+
"list_double" => [[{"@value" => "1", "@type" => RDF::XSD.double.to_s}]],
|
1063
|
+
"list_date" => [[{"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}]],
|
998
1064
|
}.each do |prop, values|
|
999
1065
|
context "uses #{prop}" do
|
1000
1066
|
values.each do |value|
|
1001
1067
|
it "for #{{"@list" => value}.inspect}" do
|
1002
|
-
expect(ctx.compact_iri("http://example.com/#{prop.sub(
|
1068
|
+
expect(ctx.compact_iri("http://example.com/#{prop.sub(/^\w+_/, '')}", value: {"@list" => value}, vocab: true)).
|
1003
1069
|
to produce(prop, logger)
|
1004
1070
|
end
|
1005
1071
|
end
|
data/spec/expand_spec.rb
CHANGED
@@ -141,6 +141,141 @@ describe JSON::LD::API do
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
+
context "with relative property IRIs" do
|
145
|
+
{
|
146
|
+
"base": {
|
147
|
+
input: %({
|
148
|
+
"http://a/b": "foo"
|
149
|
+
}),
|
150
|
+
output: %([{
|
151
|
+
"http://a/b": [{"@value": "foo"}]
|
152
|
+
}])
|
153
|
+
},
|
154
|
+
"relative": {
|
155
|
+
input: %({
|
156
|
+
"a/b": "foo"
|
157
|
+
}),
|
158
|
+
output: %([])
|
159
|
+
},
|
160
|
+
"hash": {
|
161
|
+
input: %({
|
162
|
+
"#a": "foo"
|
163
|
+
}),
|
164
|
+
output: %([])
|
165
|
+
},
|
166
|
+
"dotseg": {
|
167
|
+
input: %({
|
168
|
+
"../a": "foo"
|
169
|
+
}),
|
170
|
+
output: %([])
|
171
|
+
},
|
172
|
+
}.each do |title, params|
|
173
|
+
it(title) {run_expand params.merge(base: "http://example.org/")}
|
174
|
+
end
|
175
|
+
|
176
|
+
context "with @vocab" do
|
177
|
+
{
|
178
|
+
"base": {
|
179
|
+
input: %({
|
180
|
+
"@context": {"@vocab": "http://vocab/"},
|
181
|
+
"http://a/b": "foo"
|
182
|
+
}),
|
183
|
+
output: %([{
|
184
|
+
"http://a/b": [{"@value": "foo"}]
|
185
|
+
}])
|
186
|
+
},
|
187
|
+
"relative": {
|
188
|
+
input: %({
|
189
|
+
"@context": {"@vocab": "http://vocab/"},
|
190
|
+
"a/b": "foo"
|
191
|
+
}),
|
192
|
+
output: %([{
|
193
|
+
"http://vocab/a/b": [{"@value": "foo"}]
|
194
|
+
}])
|
195
|
+
},
|
196
|
+
"hash": {
|
197
|
+
input: %({
|
198
|
+
"@context": {"@vocab": "http://vocab/"},
|
199
|
+
"#a": "foo"
|
200
|
+
}),
|
201
|
+
output: %([{
|
202
|
+
"http://vocab/#a": [{"@value": "foo"}]
|
203
|
+
}])
|
204
|
+
},
|
205
|
+
"dotseg": {
|
206
|
+
input: %({
|
207
|
+
"@context": {"@vocab": "http://vocab/"},
|
208
|
+
"../a": "foo"
|
209
|
+
}),
|
210
|
+
output: %([{
|
211
|
+
"http://vocab/../a": [{"@value": "foo"}]
|
212
|
+
}])
|
213
|
+
},
|
214
|
+
}.each do |title, params|
|
215
|
+
it(title) {run_expand params.merge(base: "http://example.org/")}
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "with @vocab: ''" do
|
220
|
+
{
|
221
|
+
"base": {
|
222
|
+
input: %({
|
223
|
+
"@context": {"@vocab": ""},
|
224
|
+
"http://a/b": "foo"
|
225
|
+
}),
|
226
|
+
output: %([{
|
227
|
+
"http://a/b": [{"@value": "foo"}]
|
228
|
+
}])
|
229
|
+
},
|
230
|
+
"relative": {
|
231
|
+
input: %({
|
232
|
+
"@context": {"@vocab": ""},
|
233
|
+
"a/b": "foo"
|
234
|
+
}),
|
235
|
+
output: %([{
|
236
|
+
"http://example.org/a/b": [{"@value": "foo"}]
|
237
|
+
}])
|
238
|
+
},
|
239
|
+
"hash": {
|
240
|
+
input: %({
|
241
|
+
"@context": {"@vocab": ""},
|
242
|
+
"#a": "foo"
|
243
|
+
}),
|
244
|
+
output: %([{
|
245
|
+
"http://example.org/#a": [{"@value": "foo"}]
|
246
|
+
}])
|
247
|
+
},
|
248
|
+
"dotseg": {
|
249
|
+
input: %({
|
250
|
+
"@context": {"@vocab": ""},
|
251
|
+
"../a": "foo"
|
252
|
+
}),
|
253
|
+
output: %([{
|
254
|
+
"http://example.org/../a": [{"@value": "foo"}]
|
255
|
+
}])
|
256
|
+
},
|
257
|
+
"example": {
|
258
|
+
input: %({
|
259
|
+
"@context": {
|
260
|
+
"@base": "http://example/document",
|
261
|
+
"@vocab": ""
|
262
|
+
},
|
263
|
+
"@id": "http://example.org/places#BrewEats",
|
264
|
+
"@type": "#Restaurant",
|
265
|
+
"#name": "Brew Eats"
|
266
|
+
}),
|
267
|
+
output: %([{
|
268
|
+
"@id": "http://example.org/places#BrewEats",
|
269
|
+
"@type": ["http://example/document#Restaurant"],
|
270
|
+
"http://example/document#name": [{"@value": "Brew Eats"}]
|
271
|
+
}])
|
272
|
+
}
|
273
|
+
}.each do |title, params|
|
274
|
+
it(title) {run_expand params.merge(base: "http://example.org/")}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
144
279
|
context "keyword aliasing" do
|
145
280
|
{
|
146
281
|
"@id": {
|
@@ -671,24 +806,98 @@ describe JSON::LD::API do
|
|
671
806
|
])
|
672
807
|
},
|
673
808
|
"@list containing @list" => {
|
674
|
-
input: {
|
675
|
-
"http://example.com/foo"
|
676
|
-
},
|
677
|
-
|
809
|
+
input: %({
|
810
|
+
"http://example.com/foo": {"@list": [{"@list": ["baz"]}]}
|
811
|
+
}),
|
812
|
+
output: %([{
|
813
|
+
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
814
|
+
}])
|
815
|
+
},
|
816
|
+
"@list containing empty @list" => {
|
817
|
+
input: %({
|
818
|
+
"http://example.com/foo": {"@list": [{"@list": []}]}
|
819
|
+
}),
|
820
|
+
output: %([{
|
821
|
+
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
822
|
+
}])
|
678
823
|
},
|
679
824
|
"@list containing @list (with coercion)" => {
|
680
|
-
input: {
|
681
|
-
"@context"
|
682
|
-
"foo"
|
683
|
-
},
|
684
|
-
|
825
|
+
input: %({
|
826
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
827
|
+
"foo": [{"@list": ["baz"]}]
|
828
|
+
}),
|
829
|
+
output: %([{
|
830
|
+
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
831
|
+
}])
|
832
|
+
},
|
833
|
+
"@list containing empty @list (with coercion)" => {
|
834
|
+
input: %({
|
835
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
836
|
+
"foo": [{"@list": []}]
|
837
|
+
}),
|
838
|
+
output: %([{
|
839
|
+
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
840
|
+
}])
|
685
841
|
},
|
686
842
|
"coerced @list containing an array" => {
|
687
|
-
input: {
|
688
|
-
"@context"
|
689
|
-
"foo"
|
690
|
-
},
|
691
|
-
|
843
|
+
input: %({
|
844
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
845
|
+
"foo": [["baz"]]
|
846
|
+
}),
|
847
|
+
output: %([{
|
848
|
+
"http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
|
849
|
+
}])
|
850
|
+
},
|
851
|
+
"coerced @list containing an empty array" => {
|
852
|
+
input: %({
|
853
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
854
|
+
"foo": [[]]
|
855
|
+
}),
|
856
|
+
output: %([{
|
857
|
+
"http://example.com/foo": [{"@list": [{"@list": []}]}]
|
858
|
+
}])
|
859
|
+
},
|
860
|
+
"coerced @list containing deep arrays" => {
|
861
|
+
input: %({
|
862
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
863
|
+
"foo": [[["baz"]]]
|
864
|
+
}),
|
865
|
+
output: %([{
|
866
|
+
"http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
|
867
|
+
}])
|
868
|
+
},
|
869
|
+
"coerced @list containing deep empty arrays" => {
|
870
|
+
input: %({
|
871
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
872
|
+
"foo": [[[]]]
|
873
|
+
}),
|
874
|
+
output: %([{
|
875
|
+
"http://example.com/foo": [{"@list": [{"@list": [{"@list": []}]}]}]
|
876
|
+
}]),
|
877
|
+
},
|
878
|
+
"coerced @list containing multiple lists" => {
|
879
|
+
input: %({
|
880
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
881
|
+
"foo": [["a"], ["b"]]
|
882
|
+
}),
|
883
|
+
output: %([{
|
884
|
+
"http://example.com/foo": [{"@list": [
|
885
|
+
{"@list": [{"@value": "a"}]},
|
886
|
+
{"@list": [{"@value": "b"}]}
|
887
|
+
]}]
|
888
|
+
}])
|
889
|
+
},
|
890
|
+
"coerced @list containing mixed list values" => {
|
891
|
+
input: %({
|
892
|
+
"@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
|
893
|
+
"foo": [["a"], "b"]
|
894
|
+
}),
|
895
|
+
output: %([{
|
896
|
+
"http://example.com/foo": [{"@list": [
|
897
|
+
{"@list": [{"@value": "a"}]},
|
898
|
+
{"@value": "b"}
|
899
|
+
]}]
|
900
|
+
}])
|
692
901
|
},
|
693
902
|
}.each do |title, params|
|
694
903
|
it(title) {run_expand params}
|
@@ -796,6 +1005,63 @@ describe JSON::LD::API do
|
|
796
1005
|
}
|
797
1006
|
]
|
798
1007
|
},
|
1008
|
+
"simple map with @none" => {
|
1009
|
+
input: {
|
1010
|
+
"@context" => {
|
1011
|
+
"vocab" => "http://example.com/vocab/",
|
1012
|
+
"label" => {
|
1013
|
+
"@id" => "vocab:label",
|
1014
|
+
"@container" => "@language"
|
1015
|
+
}
|
1016
|
+
},
|
1017
|
+
"@id" => "http://example.com/queen",
|
1018
|
+
"label" => {
|
1019
|
+
"en" => "The Queen",
|
1020
|
+
"de" => [ "Die Königin", "Ihre Majestät" ],
|
1021
|
+
"@none" => "The Queen"
|
1022
|
+
}
|
1023
|
+
},
|
1024
|
+
output: [
|
1025
|
+
{
|
1026
|
+
"@id" => "http://example.com/queen",
|
1027
|
+
"http://example.com/vocab/label" => [
|
1028
|
+
{"@value" => "The Queen"},
|
1029
|
+
{"@value" => "Die Königin", "@language" => "de"},
|
1030
|
+
{"@value" => "Ihre Majestät", "@language" => "de"},
|
1031
|
+
{"@value" => "The Queen", "@language" => "en"},
|
1032
|
+
]
|
1033
|
+
}
|
1034
|
+
]
|
1035
|
+
},
|
1036
|
+
"simple map with alias of @none" => {
|
1037
|
+
input: {
|
1038
|
+
"@context" => {
|
1039
|
+
"vocab" => "http://example.com/vocab/",
|
1040
|
+
"label" => {
|
1041
|
+
"@id" => "vocab:label",
|
1042
|
+
"@container" => "@language"
|
1043
|
+
},
|
1044
|
+
"none" => "@none"
|
1045
|
+
},
|
1046
|
+
"@id" => "http://example.com/queen",
|
1047
|
+
"label" => {
|
1048
|
+
"en" => "The Queen",
|
1049
|
+
"de" => [ "Die Königin", "Ihre Majestät" ],
|
1050
|
+
"none" => "The Queen"
|
1051
|
+
}
|
1052
|
+
},
|
1053
|
+
output: [
|
1054
|
+
{
|
1055
|
+
"@id" => "http://example.com/queen",
|
1056
|
+
"http://example.com/vocab/label" => [
|
1057
|
+
{"@value" => "Die Königin", "@language" => "de"},
|
1058
|
+
{"@value" => "Ihre Majestät", "@language" => "de"},
|
1059
|
+
{"@value" => "The Queen", "@language" => "en"},
|
1060
|
+
{"@value" => "The Queen"},
|
1061
|
+
]
|
1062
|
+
}
|
1063
|
+
]
|
1064
|
+
},
|
799
1065
|
"expand-0035" => {
|
800
1066
|
input: {
|
801
1067
|
"@context" => {
|
@@ -902,6 +1168,25 @@ describe JSON::LD::API do
|
|
902
1168
|
processingMode: nil,
|
903
1169
|
exception: JSON::LD::JsonLdError::InvalidContainerMapping
|
904
1170
|
},
|
1171
|
+
"Does not add @id if it is @none, or expands to @none": {
|
1172
|
+
input: %({
|
1173
|
+
"@context": {
|
1174
|
+
"@vocab": "http://example/",
|
1175
|
+
"idmap": {"@container": "@id"},
|
1176
|
+
"none": "@none"
|
1177
|
+
},
|
1178
|
+
"idmap": {
|
1179
|
+
"@none": {"label": "Object with no @id"},
|
1180
|
+
"none": {"label": "Another object with no @id"}
|
1181
|
+
}
|
1182
|
+
}),
|
1183
|
+
output: %([{
|
1184
|
+
"http://example/idmap": [
|
1185
|
+
{"http://example/label": [{"@value": "Object with no @id"}]},
|
1186
|
+
{"http://example/label": [{"@value": "Another object with no @id"}]}
|
1187
|
+
]
|
1188
|
+
}])
|
1189
|
+
}
|
905
1190
|
}.each do |title, params|
|
906
1191
|
it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
|
907
1192
|
end
|
@@ -970,7 +1255,8 @@ describe JSON::LD::API do
|
|
970
1255
|
"Adds document expanded @type to object" => {
|
971
1256
|
input: %({
|
972
1257
|
"@context": {
|
973
|
-
"
|
1258
|
+
"@vocab": "http://example/",
|
1259
|
+
"typemap": {"@container": "@type"},
|
974
1260
|
"label": "http://example/label"
|
975
1261
|
},
|
976
1262
|
"typemap": {
|
@@ -979,10 +1265,28 @@ describe JSON::LD::API do
|
|
979
1265
|
}),
|
980
1266
|
output: %([{
|
981
1267
|
"http://example/typemap": [
|
982
|
-
{"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example
|
1268
|
+
{"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example/Foo"]}
|
983
1269
|
]
|
984
|
-
}])
|
985
|
-
|
1270
|
+
}])
|
1271
|
+
},
|
1272
|
+
"Does not add @type if it is @none, or expands to @none": {
|
1273
|
+
input: %({
|
1274
|
+
"@context": {
|
1275
|
+
"@vocab": "http://example/",
|
1276
|
+
"typemap": {"@container": "@type"},
|
1277
|
+
"none": "@none"
|
1278
|
+
},
|
1279
|
+
"typemap": {
|
1280
|
+
"@none": {"label": "Object with no @type"},
|
1281
|
+
"none": {"label": "Another object with no @type"}
|
1282
|
+
}
|
1283
|
+
}),
|
1284
|
+
output: %([{
|
1285
|
+
"http://example/typemap": [
|
1286
|
+
{"http://example/label": [{"@value": "Object with no @type"}]},
|
1287
|
+
{"http://example/label": [{"@value": "Another object with no @type"}]}
|
1288
|
+
]
|
1289
|
+
}])
|
986
1290
|
},
|
987
1291
|
"Raises InvalidContainerMapping if processingMode is not specified" => {
|
988
1292
|
input: %({
|
@@ -1086,6 +1390,43 @@ describe JSON::LD::API do
|
|
1086
1390
|
}]
|
1087
1391
|
}])
|
1088
1392
|
},
|
1393
|
+
"Creates a graph object given an indexed value with index @none" => {
|
1394
|
+
input: %({
|
1395
|
+
"@context": {
|
1396
|
+
"@vocab": "http://example.org/",
|
1397
|
+
"input": {"@container": ["@graph", "@index"]}
|
1398
|
+
},
|
1399
|
+
"input": {
|
1400
|
+
"@none": {"value": "x"}
|
1401
|
+
}
|
1402
|
+
}),
|
1403
|
+
output: %([{
|
1404
|
+
"http://example.org/input": [{
|
1405
|
+
"@graph": [{
|
1406
|
+
"http://example.org/value": [{"@value": "x"}]
|
1407
|
+
}]
|
1408
|
+
}]
|
1409
|
+
}])
|
1410
|
+
},
|
1411
|
+
"Creates a graph object given an indexed value with index alias of @none" => {
|
1412
|
+
input: %({
|
1413
|
+
"@context": {
|
1414
|
+
"@vocab": "http://example.org/",
|
1415
|
+
"input": {"@container": ["@graph", "@index"]},
|
1416
|
+
"none": "@none"
|
1417
|
+
},
|
1418
|
+
"input": {
|
1419
|
+
"none": {"value": "x"}
|
1420
|
+
}
|
1421
|
+
}),
|
1422
|
+
output: %([{
|
1423
|
+
"http://example.org/input": [{
|
1424
|
+
"@graph": [{
|
1425
|
+
"http://example.org/value": [{"@value": "x"}]
|
1426
|
+
}]
|
1427
|
+
}]
|
1428
|
+
}])
|
1429
|
+
},
|
1089
1430
|
"Creates a graph object given an indexed value with @set" => {
|
1090
1431
|
input: %({
|
1091
1432
|
"@context": {
|
@@ -1154,6 +1495,43 @@ describe JSON::LD::API do
|
|
1154
1495
|
}]
|
1155
1496
|
}])
|
1156
1497
|
},
|
1498
|
+
"Creates a graph object given an indexed value of @none" => {
|
1499
|
+
input: %({
|
1500
|
+
"@context": {
|
1501
|
+
"@vocab": "http://example.org/",
|
1502
|
+
"input": {"@container": ["@graph", "@id"]}
|
1503
|
+
},
|
1504
|
+
"input": {
|
1505
|
+
"@none": {"value": "x"}
|
1506
|
+
}
|
1507
|
+
}),
|
1508
|
+
output: %([{
|
1509
|
+
"http://example.org/input": [{
|
1510
|
+
"@graph": [{
|
1511
|
+
"http://example.org/value": [{"@value": "x"}]
|
1512
|
+
}]
|
1513
|
+
}]
|
1514
|
+
}])
|
1515
|
+
},
|
1516
|
+
"Creates a graph object given an indexed value of alias of @none" => {
|
1517
|
+
input: %({
|
1518
|
+
"@context": {
|
1519
|
+
"@vocab": "http://example.org/",
|
1520
|
+
"input": {"@container": ["@graph", "@id"]},
|
1521
|
+
"none": "@none"
|
1522
|
+
},
|
1523
|
+
"input": {
|
1524
|
+
"none": {"value": "x"}
|
1525
|
+
}
|
1526
|
+
}),
|
1527
|
+
output: %([{
|
1528
|
+
"http://example.org/input": [{
|
1529
|
+
"@graph": [{
|
1530
|
+
"http://example.org/value": [{"@value": "x"}]
|
1531
|
+
}]
|
1532
|
+
}]
|
1533
|
+
}])
|
1534
|
+
},
|
1157
1535
|
"Creates a graph object given an indexed value with @set" => {
|
1158
1536
|
input: %({
|
1159
1537
|
"@context": {
|
@@ -1779,6 +2157,23 @@ describe JSON::LD::API do
|
|
1779
2157
|
]
|
1780
2158
|
}])
|
1781
2159
|
},
|
2160
|
+
"orders lexicographically" => {
|
2161
|
+
input: %({
|
2162
|
+
"@context": {
|
2163
|
+
"@vocab": "http://example/",
|
2164
|
+
"t1": {"@context": {"foo": {"@id": "http://example.com/foo"}}},
|
2165
|
+
"t2": {"@context": {"foo": {"@id": "http://example.org/foo", "@type": "@id"}}}
|
2166
|
+
},
|
2167
|
+
"@type": ["t2", "t1"],
|
2168
|
+
"foo": "urn:bar"
|
2169
|
+
}),
|
2170
|
+
output: %([{
|
2171
|
+
"@type": ["http://example/t2", "http://example/t1"],
|
2172
|
+
"http://example.org/foo": [
|
2173
|
+
{"@id": "urn:bar"}
|
2174
|
+
]
|
2175
|
+
}])
|
2176
|
+
},
|
1782
2177
|
"Raises InvalidTermDefinition if processingMode is not specified" => {
|
1783
2178
|
input: %({
|
1784
2179
|
"@context": {
|