json-ld 2.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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": {
|