json-ld 3.0.2 → 3.1.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 +4 -4
- data/AUTHORS +1 -1
- data/README.md +90 -53
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/jsonld +4 -4
- data/lib/json/ld.rb +27 -10
- data/lib/json/ld/api.rb +325 -96
- data/lib/json/ld/compact.rb +75 -27
- data/lib/json/ld/conneg.rb +188 -0
- data/lib/json/ld/context.rb +677 -292
- data/lib/json/ld/expand.rb +240 -75
- data/lib/json/ld/flatten.rb +5 -3
- data/lib/json/ld/format.rb +19 -19
- data/lib/json/ld/frame.rb +135 -85
- data/lib/json/ld/from_rdf.rb +44 -17
- data/lib/json/ld/html/nokogiri.rb +151 -0
- data/lib/json/ld/html/rexml.rb +186 -0
- data/lib/json/ld/reader.rb +25 -5
- data/lib/json/ld/resource.rb +2 -2
- data/lib/json/ld/streaming_writer.rb +3 -1
- data/lib/json/ld/to_rdf.rb +47 -17
- data/lib/json/ld/utils.rb +4 -2
- data/lib/json/ld/writer.rb +75 -14
- data/spec/api_spec.rb +13 -34
- data/spec/compact_spec.rb +968 -9
- data/spec/conneg_spec.rb +373 -0
- data/spec/context_spec.rb +447 -53
- data/spec/expand_spec.rb +1872 -416
- data/spec/flatten_spec.rb +434 -47
- data/spec/frame_spec.rb +979 -344
- data/spec/from_rdf_spec.rb +305 -5
- data/spec/spec_helper.rb +177 -0
- data/spec/streaming_writer_spec.rb +4 -4
- data/spec/suite_compact_spec.rb +2 -2
- data/spec/suite_expand_spec.rb +14 -2
- data/spec/suite_flatten_spec.rb +10 -2
- data/spec/suite_frame_spec.rb +3 -2
- data/spec/suite_from_rdf_spec.rb +2 -2
- data/spec/suite_helper.rb +55 -20
- data/spec/suite_html_spec.rb +22 -0
- data/spec/suite_http_spec.rb +35 -0
- data/spec/suite_remote_doc_spec.rb +2 -2
- data/spec/suite_to_rdf_spec.rb +14 -3
- data/spec/support/extensions.rb +5 -1
- data/spec/test-files/test-4-input.json +3 -3
- data/spec/test-files/test-5-input.json +2 -2
- data/spec/test-files/test-8-framed.json +14 -18
- data/spec/to_rdf_spec.rb +606 -16
- data/spec/writer_spec.rb +5 -5
- metadata +144 -88
data/spec/conneg_spec.rb
ADDED
@@ -0,0 +1,373 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'spec_helper'
|
3
|
+
require 'rack/linkeddata'
|
4
|
+
require 'rack/test'
|
5
|
+
|
6
|
+
describe JSON::LD::ContentNegotiation do
|
7
|
+
include ::Rack::Test::Methods
|
8
|
+
let(:logger) {RDF::Spec.logger}
|
9
|
+
|
10
|
+
let(:app) do
|
11
|
+
described_class.new(double("Target Rack Application", :call => [200, {}, @results || "A String"]))
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#parse_accept_header" do
|
15
|
+
{
|
16
|
+
"application/n-triples, application/ld+json;q=0.5" => %w(application/ld+json),
|
17
|
+
"application/ld+json, application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted" =>
|
18
|
+
%w(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted application/ld+json),
|
19
|
+
}.each do |accept, content_types|
|
20
|
+
it "returns #{content_types.inspect} given #{accept.inspect}" do
|
21
|
+
expect(app.send(:parse_accept_header, accept)).to eq content_types
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#find_content_type_for_media_range" do
|
27
|
+
{
|
28
|
+
"*/*" => "application/ld+json",
|
29
|
+
"application/*" => "application/ld+json",
|
30
|
+
"application/json" => "application/ld+json",
|
31
|
+
"application/json;profile=http://www.w3.org/ns/json-ld#compacted" =>
|
32
|
+
"application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted",
|
33
|
+
"text/plain" => nil
|
34
|
+
}.each do |media_range, content_type|
|
35
|
+
it "returns #{content_type.inspect} for #{media_range.inspect}" do
|
36
|
+
expect(app.send(:find_content_type_for_media_range, media_range)).to eq content_type
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#call" do
|
42
|
+
let(:schema_context) {
|
43
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
44
|
+
"@context": {
|
45
|
+
"@vocab": "http://schema.org/",
|
46
|
+
"id": "@id",
|
47
|
+
"type": "@type"
|
48
|
+
}
|
49
|
+
}), documentUrl: "http://schema.org")
|
50
|
+
}
|
51
|
+
let(:frame) {
|
52
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
53
|
+
"@context": {
|
54
|
+
"dc": "http://purl.org/dc/elements/1.1/",
|
55
|
+
"ex": "http://example.org/vocab#"
|
56
|
+
},
|
57
|
+
"@type": "ex:Library",
|
58
|
+
"ex:contains": {
|
59
|
+
"@type": "ex:Book",
|
60
|
+
"ex:contains": {
|
61
|
+
"@type": "ex:Chapter"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}), documentUrl: "http://conneg.example.com/frame")
|
65
|
+
}
|
66
|
+
let(:context) {
|
67
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
68
|
+
"@context": {
|
69
|
+
"dc": "http://purl.org/dc/elements/1.1/",
|
70
|
+
"ex": "http://example.org/vocab#"
|
71
|
+
}
|
72
|
+
}), documentUrl: "http://conneg.example.com/context")
|
73
|
+
}
|
74
|
+
|
75
|
+
before(:each) do
|
76
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://schema.org", any_args).and_yield(schema_context)
|
77
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", any_args).and_yield(context)
|
78
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", any_args).and_yield(frame)
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with text result" do
|
82
|
+
it "returns text unchanged" do
|
83
|
+
get '/'
|
84
|
+
expect(last_response.body).to eq 'A String'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "with object result" do
|
89
|
+
before(:each) do
|
90
|
+
@results = LIBRARY_INPUT
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns expanded result" do
|
94
|
+
get '/'
|
95
|
+
expect(JSON.parse(last_response.body)).to produce_jsonld(LIBRARY_INPUT, logger)
|
96
|
+
end
|
97
|
+
|
98
|
+
context "with Accept" do
|
99
|
+
{
|
100
|
+
"application/n-triples" => "406 Not Acceptable (No appropriate combinaion of media-type and parameters found)\n",
|
101
|
+
"application/json" => LIBRARY_INPUT,
|
102
|
+
"application/ld+json" => LIBRARY_INPUT,
|
103
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded) =>
|
104
|
+
LIBRARY_EXPANDED,
|
105
|
+
|
106
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted) =>
|
107
|
+
LIBRARY_COMPACTED_DEFAULT,
|
108
|
+
|
109
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#flattened) =>
|
110
|
+
LIBRARY_FLATTENED_EXPANDED,
|
111
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#expanded") =>
|
112
|
+
LIBRARY_FLATTENED_EXPANDED,
|
113
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#expanded http://www.w3.org/ns/json-ld#flattened") =>
|
114
|
+
LIBRARY_FLATTENED_EXPANDED,
|
115
|
+
|
116
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted") =>
|
117
|
+
LIBRARY_FLATTENED_COMPACTED_DEFAULT,
|
118
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#flattened") =>
|
119
|
+
LIBRARY_FLATTENED_COMPACTED_DEFAULT,
|
120
|
+
|
121
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed) =>
|
122
|
+
"406 Not Acceptable (framed profile without a frame)\n",
|
123
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#framed http://www.w3.org/ns/json-ld#expanded") =>
|
124
|
+
"406 Not Acceptable (framed profile without a frame)\n",
|
125
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#expanded http://www.w3.org/ns/json-ld#framed") =>
|
126
|
+
"406 Not Acceptable (framed profile without a frame)\n",
|
127
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#framed http://www.w3.org/ns/json-ld#compacted") =>
|
128
|
+
"406 Not Acceptable (framed profile without a frame)\n",
|
129
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#framed") =>
|
130
|
+
"406 Not Acceptable (framed profile without a frame)\n",
|
131
|
+
}.each do |accepts, result|
|
132
|
+
context accepts do
|
133
|
+
before(:each) do
|
134
|
+
get '/', {}, {"HTTP_ACCEPT" => accepts}
|
135
|
+
end
|
136
|
+
|
137
|
+
it "status" do
|
138
|
+
expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)}
|
139
|
+
end
|
140
|
+
|
141
|
+
it "sets content type" do
|
142
|
+
expect(last_response.content_type).to eq(last_response.status == 406 ? 'text/plain' : 'application/ld+json')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns serialization" do
|
146
|
+
if last_response.status == 406
|
147
|
+
expect(last_response.body).to eq result
|
148
|
+
else
|
149
|
+
expect(JSON.parse(last_response.body)).to produce_jsonld(result, logger)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with Link" do
|
157
|
+
{
|
158
|
+
"compacted with context" => {
|
159
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted),
|
160
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
161
|
+
result: LIBRARY_COMPACTED
|
162
|
+
},
|
163
|
+
"flattened with context" => {
|
164
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#flattened),
|
165
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
166
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
167
|
+
},
|
168
|
+
"flattened and compacted with context" => {
|
169
|
+
accept: %(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted"),
|
170
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
171
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
172
|
+
},
|
173
|
+
"compacted and flattened with context" => {
|
174
|
+
accept: %(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#flattened"),
|
175
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
176
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
177
|
+
},
|
178
|
+
"framed with frame" => {
|
179
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed),
|
180
|
+
link: %(<http://conneg.example.com/frame> rel="http://www.w3.org/ns/json-ld#frame"),
|
181
|
+
result: LIBRARY_FRAMED
|
182
|
+
},
|
183
|
+
|
184
|
+
"framed with context" => {
|
185
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed),
|
186
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
187
|
+
result: "406 Not Acceptable (framed profile without a frame)\n"
|
188
|
+
},
|
189
|
+
}.each do |name, params|
|
190
|
+
context name do
|
191
|
+
before(:each) do
|
192
|
+
get '/', {}, {"HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link]}
|
193
|
+
end
|
194
|
+
|
195
|
+
it "status" do
|
196
|
+
expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)}
|
197
|
+
end
|
198
|
+
|
199
|
+
it "sets content type" do
|
200
|
+
expect(last_response.content_type).to eq(last_response.status == 406 ? 'text/plain' : 'application/ld+json')
|
201
|
+
end
|
202
|
+
|
203
|
+
it "returns serialization" do
|
204
|
+
if last_response.status == 406
|
205
|
+
expect(last_response.body).to eq params[:result]
|
206
|
+
else
|
207
|
+
expect(JSON.parse(last_response.body)).to produce_jsonld(params[:result], logger)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe Rack::LinkedData::ContentNegotiation do
|
218
|
+
include ::Rack::Test::Methods
|
219
|
+
let(:logger) {RDF::Spec.logger}
|
220
|
+
|
221
|
+
let(:app) do
|
222
|
+
graph = RDF::NTriples::Reader.new(%(
|
223
|
+
<http://example.org/library> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/vocab#Library> .
|
224
|
+
<http://example.org/library> <http://example.org/vocab#contains> <http://example.org/library/the-republic> .
|
225
|
+
<http://example.org/library/the-republic> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/vocab#Book> .
|
226
|
+
<http://example.org/library/the-republic> <http://purl.org/dc/elements/1.1/title> "The Republic" .
|
227
|
+
<http://example.org/library/the-republic> <http://purl.org/dc/elements/1.1/creator> "Plato" .
|
228
|
+
<http://example.org/library/the-republic> <http://example.org/vocab#contains> <http://example.org/library/the-republic#introduction> .
|
229
|
+
<http://example.org/library/the-republic#introduction> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/vocab#Chapter> .
|
230
|
+
<http://example.org/library/the-republic#introduction> <http://purl.org/dc/elements/1.1/title> "The Introduction" .
|
231
|
+
<http://example.org/library/the-republic#introduction> <http://purl.org/dc/elements/1.1/description> "An introductory chapter on The Republic." .
|
232
|
+
))
|
233
|
+
Rack::LinkedData::ContentNegotiation.new(double("Target Rack Application", :call => [200, {}, graph]), {})
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "#call" do
|
237
|
+
let(:schema_context) {
|
238
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
239
|
+
"@context": {
|
240
|
+
"@vocab": "http://schema.org/",
|
241
|
+
"id": "@id",
|
242
|
+
"type": "@type"
|
243
|
+
}
|
244
|
+
}), documentUrl: "http://schema.org")
|
245
|
+
}
|
246
|
+
let(:frame) {
|
247
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
248
|
+
"@context": {
|
249
|
+
"dc": "http://purl.org/dc/elements/1.1/",
|
250
|
+
"ex": "http://example.org/vocab#"
|
251
|
+
},
|
252
|
+
"@type": "ex:Library",
|
253
|
+
"ex:contains": {
|
254
|
+
"@type": "ex:Book",
|
255
|
+
"ex:contains": {
|
256
|
+
"@type": "ex:Chapter"
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}), documentUrl: "http://conneg.example.com/frame")
|
260
|
+
}
|
261
|
+
let(:context) {
|
262
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
263
|
+
"@context": {
|
264
|
+
"dc": "http://purl.org/dc/elements/1.1/",
|
265
|
+
"ex": "http://example.org/vocab#"
|
266
|
+
}
|
267
|
+
}), documentUrl: "http://conneg.example.com/context")
|
268
|
+
}
|
269
|
+
|
270
|
+
before(:each) do
|
271
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://schema.org", any_args).and_yield(schema_context)
|
272
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/context", any_args).and_yield(context)
|
273
|
+
allow(JSON::LD::API).to receive(:documentLoader).with("http://conneg.example.com/frame", any_args).and_yield(frame)
|
274
|
+
end
|
275
|
+
|
276
|
+
{
|
277
|
+
"application/json" => LIBRARY_FLATTENED_EXPANDED,
|
278
|
+
"application/ld+json" => LIBRARY_FLATTENED_EXPANDED,
|
279
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded) =>
|
280
|
+
LIBRARY_FLATTENED_EXPANDED,
|
281
|
+
|
282
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted) =>
|
283
|
+
LIBRARY_FLATTENED_COMPACTED_DEFAULT,
|
284
|
+
|
285
|
+
%(application/ld+json;profile=http://www.w3.org/ns/json-ld#flattened) =>
|
286
|
+
LIBRARY_FLATTENED_EXPANDED,
|
287
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#expanded") =>
|
288
|
+
LIBRARY_FLATTENED_EXPANDED,
|
289
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#expanded http://www.w3.org/ns/json-ld#flattened") =>
|
290
|
+
LIBRARY_FLATTENED_EXPANDED,
|
291
|
+
|
292
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted") =>
|
293
|
+
LIBRARY_FLATTENED_COMPACTED_DEFAULT,
|
294
|
+
%(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#flattened") =>
|
295
|
+
LIBRARY_FLATTENED_COMPACTED_DEFAULT,
|
296
|
+
|
297
|
+
}.each do |accepts, result|
|
298
|
+
context accepts do
|
299
|
+
before(:each) do
|
300
|
+
get '/', {}, {"HTTP_ACCEPT" => accepts}
|
301
|
+
end
|
302
|
+
|
303
|
+
it "status" do
|
304
|
+
expect(last_response.status).to satisfy("200 or 406") {|x| [200, 406].include?(x)}
|
305
|
+
end
|
306
|
+
|
307
|
+
it "sets content type" do
|
308
|
+
expect(last_response.content_type).to eq(last_response.status == 406 ? 'text/plain' : 'application/ld+json')
|
309
|
+
end
|
310
|
+
|
311
|
+
it "returns serialization" do
|
312
|
+
if last_response.status == 406
|
313
|
+
expect(last_response.body).to eq result
|
314
|
+
else
|
315
|
+
expect(JSON.parse(last_response.body)).to produce_jsonld(result, logger)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "with Link" do
|
322
|
+
{
|
323
|
+
"with context" => {
|
324
|
+
accept: %(application/ld+json),
|
325
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
326
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
327
|
+
},
|
328
|
+
"compacted with context" => {
|
329
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#compacted),
|
330
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
331
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
332
|
+
},
|
333
|
+
"flattened and compacted with context" => {
|
334
|
+
accept: %(application/ld+json;profile="http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted"),
|
335
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
336
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
337
|
+
},
|
338
|
+
"compacted and flattened with context" => {
|
339
|
+
accept: %(application/ld+json;profile="http://www.w3.org/ns/json-ld#compacted http://www.w3.org/ns/json-ld#flattened"),
|
340
|
+
link: %(<http://conneg.example.com/context> rel="http://www.w3.org/ns/json-ld#context"),
|
341
|
+
result: LIBRARY_FLATTENED_COMPACTED
|
342
|
+
},
|
343
|
+
"framed with frame" => {
|
344
|
+
accept: %(application/ld+json;profile=http://www.w3.org/ns/json-ld#framed),
|
345
|
+
link: %(<http://conneg.example.com/frame> rel="http://www.w3.org/ns/json-ld#frame"),
|
346
|
+
result: LIBRARY_FRAMED
|
347
|
+
},
|
348
|
+
}.each do |name, params|
|
349
|
+
context name do
|
350
|
+
before(:each) do
|
351
|
+
get '/', {}, {"HTTP_ACCEPT" => params[:accept], "HTTP_LINK" => params[:link]}
|
352
|
+
end
|
353
|
+
|
354
|
+
it "status" do
|
355
|
+
expect(last_response.status).to satisfy("be 200 or 406") {|x| [200, 406].include?(x)}
|
356
|
+
end
|
357
|
+
|
358
|
+
it "sets content type" do
|
359
|
+
expect(last_response.content_type).to eq(last_response.status == 406 ? 'text/plain' : 'application/ld+json')
|
360
|
+
end
|
361
|
+
|
362
|
+
it "returns serialization" do
|
363
|
+
if last_response.status == 406
|
364
|
+
expect(last_response.body).to eq params[:result]
|
365
|
+
else
|
366
|
+
expect(JSON.parse(last_response.body)).to produce_jsonld(params[:result], logger)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
data/spec/context_spec.rb
CHANGED
@@ -25,14 +25,16 @@ describe JSON::LD::Context do
|
|
25
25
|
let(:logger) {RDF::Spec.logger}
|
26
26
|
let(:context) {JSON::LD::Context.new(logger: logger, validate: true, processingMode: "json-ld-1.1", compactToRelative: true)}
|
27
27
|
let(:remote_doc) do
|
28
|
-
JSON::LD::API::RemoteDocument.new(
|
28
|
+
JSON::LD::API::RemoteDocument.new(%q({
|
29
29
|
"@context": {
|
30
30
|
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
31
31
|
"name": "http://xmlns.com/foaf/0.1/name",
|
32
32
|
"homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"},
|
33
33
|
"avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"}
|
34
34
|
}
|
35
|
-
})
|
35
|
+
}),
|
36
|
+
documentUrl: "http://example.com/context",
|
37
|
+
contentType: "application/ld+json")
|
36
38
|
end
|
37
39
|
subject {context}
|
38
40
|
|
@@ -78,13 +80,98 @@ describe JSON::LD::Context do
|
|
78
80
|
}, logger)
|
79
81
|
end
|
80
82
|
|
83
|
+
it "retrieves and parses a remote context document in HTML using the context profile" do
|
84
|
+
remote_doc =
|
85
|
+
JSON::LD::API::RemoteDocument.new(%q(
|
86
|
+
<html><head>
|
87
|
+
<script>Not This</script>
|
88
|
+
<script type="application/ld+json">
|
89
|
+
{
|
90
|
+
"@context": {
|
91
|
+
"homepage": {"@id": "http://example.com/this-would-be-wrong", "@type": "@id"},
|
92
|
+
"avatar": {"@id": "http://example.com/this-would-be-wrong", "@type": "@id"}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
</script>
|
96
|
+
<script type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
|
97
|
+
{
|
98
|
+
"@context": {
|
99
|
+
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
100
|
+
"name": "http://xmlns.com/foaf/0.1/name",
|
101
|
+
"homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"},
|
102
|
+
"avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
</script>
|
106
|
+
<script type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
|
107
|
+
{
|
108
|
+
"@context": {
|
109
|
+
"homepage": {"@id": "http://example.com/this-would-also-be-wrong", "@type": "@id"},
|
110
|
+
"avatar": {"@id": "http://example.com/this-would-also-be-wrong", "@type": "@id"}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
</script>
|
114
|
+
</head></html>
|
115
|
+
),
|
116
|
+
documentUrl: "http://example.com/context",
|
117
|
+
contentType: "text/html")
|
118
|
+
|
119
|
+
JSON::LD::Context::PRELOADED.clear
|
120
|
+
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
121
|
+
ec = subject.parse("http://example.com/context")
|
122
|
+
expect(ec.send(:mappings)).to produce({
|
123
|
+
"xsd" => "http://www.w3.org/2001/XMLSchema#",
|
124
|
+
"name" => "http://xmlns.com/foaf/0.1/name",
|
125
|
+
"homepage" => "http://xmlns.com/foaf/0.1/homepage",
|
126
|
+
"avatar" => "http://xmlns.com/foaf/0.1/avatar"
|
127
|
+
}, logger)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "retrieves and parses a remote context document in HTML" do
|
131
|
+
remote_doc =
|
132
|
+
JSON::LD::API::RemoteDocument.new(%q(
|
133
|
+
<html><head>
|
134
|
+
<script>Not This</script>
|
135
|
+
<script type="application/ld+json">
|
136
|
+
{
|
137
|
+
"@context": {
|
138
|
+
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
139
|
+
"name": "http://xmlns.com/foaf/0.1/name",
|
140
|
+
"homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"},
|
141
|
+
"avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
</script>
|
145
|
+
<script type="application/ld+json">
|
146
|
+
{
|
147
|
+
"@context": {
|
148
|
+
"homepage": {"@id": "http://example.com/this-would-also-be-wrong", "@type": "@id"},
|
149
|
+
"avatar": {"@id": "http://example.com/this-would-also-be-wrong", "@type": "@id"}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
</script>
|
153
|
+
</head></html>
|
154
|
+
),
|
155
|
+
documentUrl: "http://example.com/context",
|
156
|
+
contentType: "text/html")
|
157
|
+
JSON::LD::Context::PRELOADED.clear
|
158
|
+
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
159
|
+
ec = subject.parse("http://example.com/context")
|
160
|
+
expect(ec.send(:mappings)).to produce({
|
161
|
+
"xsd" => "http://www.w3.org/2001/XMLSchema#",
|
162
|
+
"name" => "http://xmlns.com/foaf/0.1/name",
|
163
|
+
"homepage" => "http://xmlns.com/foaf/0.1/homepage",
|
164
|
+
"avatar" => "http://xmlns.com/foaf/0.1/avatar"
|
165
|
+
}, logger)
|
166
|
+
end
|
167
|
+
|
81
168
|
it "notes non-existing @context" do
|
82
169
|
expect {subject.parse(StringIO.new("{}"))}.to raise_error(JSON::LD::JsonLdError::InvalidRemoteContext)
|
83
170
|
end
|
84
171
|
|
85
172
|
it "parses a referenced context at a relative URI" do
|
86
173
|
JSON::LD::Context::PRELOADED.clear
|
87
|
-
rd1 = JSON::LD::API::RemoteDocument.new(
|
174
|
+
rd1 = JSON::LD::API::RemoteDocument.new(%({"@context": "context"}), base_uri: "http://example.com/c1")
|
88
175
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c1", anything).and_yield(rd1)
|
89
176
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
90
177
|
ec = subject.parse("http://example.com/c1")
|
@@ -115,8 +202,10 @@ describe JSON::LD::Context do
|
|
115
202
|
let(:ctx) {"http://example.com/preloaded"}
|
116
203
|
before(:all) {
|
117
204
|
JSON::LD::Context.add_preloaded("http://example.com/preloaded",
|
118
|
-
|
119
|
-
|
205
|
+
JSON::LD::Context.parse({'foo' => "http://example.com/"})
|
206
|
+
)
|
207
|
+
JSON::LD::Context.alias_preloaded("https://example.com/preloaded", "http://example.com/preloaded")
|
208
|
+
}
|
120
209
|
after(:all) {JSON::LD::Context::PRELOADED.clear}
|
121
210
|
|
122
211
|
it "does not load referenced context" do
|
@@ -124,12 +213,24 @@ describe JSON::LD::Context do
|
|
124
213
|
subject.parse(ctx)
|
125
214
|
end
|
126
215
|
|
216
|
+
it "does not load aliased context" do
|
217
|
+
expect(JSON::LD::API).not_to receive(:documentLoader).with(ctx.sub('http', 'https'), anything)
|
218
|
+
subject.parse(ctx.sub('http', 'https'))
|
219
|
+
end
|
220
|
+
|
127
221
|
it "uses loaded context" do
|
128
222
|
ec = subject.parse(ctx)
|
129
223
|
expect(ec.send(:mappings)).to produce({
|
130
224
|
"foo" => "http://example.com/"
|
131
225
|
}, logger)
|
132
226
|
end
|
227
|
+
|
228
|
+
it "uses aliased context" do
|
229
|
+
ec = subject.parse(ctx.sub('http', 'https'))
|
230
|
+
expect(ec.send(:mappings)).to produce({
|
231
|
+
"foo" => "http://example.com/"
|
232
|
+
}, logger)
|
233
|
+
end
|
133
234
|
end
|
134
235
|
end
|
135
236
|
|
@@ -149,11 +250,11 @@ describe JSON::LD::Context do
|
|
149
250
|
|
150
251
|
it "merges definitions from remote contexts" do
|
151
252
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
152
|
-
rd2 = JSON::LD::API::RemoteDocument.new(
|
253
|
+
rd2 = JSON::LD::API::RemoteDocument.new(%q({
|
153
254
|
"@context": {
|
154
255
|
"title": {"@id": "http://purl.org/dc/terms/title"}
|
155
256
|
}
|
156
|
-
}))
|
257
|
+
}), base_uri: "http://example.com/c2")
|
157
258
|
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/c2", anything).and_yield(rd2)
|
158
259
|
ec = subject.parse(%w(http://example.com/context http://example.com/c2))
|
159
260
|
expect(ec.send(:mappings)).to produce({
|
@@ -187,6 +288,16 @@ describe JSON::LD::Context do
|
|
187
288
|
}, logger)
|
188
289
|
end
|
189
290
|
|
291
|
+
it "maps term with blank node value (with deprecation)" do
|
292
|
+
expect do
|
293
|
+
expect(subject.parse({
|
294
|
+
"foo" => "_:bn"
|
295
|
+
}).send(:mappings)).to produce({
|
296
|
+
"foo" => RDF::Node("bn")
|
297
|
+
}, logger)
|
298
|
+
end.to write("[DEPRECATION]").to(:error)
|
299
|
+
end
|
300
|
+
|
190
301
|
it "maps term with @id" do
|
191
302
|
expect(subject.parse({
|
192
303
|
"foo" => {"@id" => "http://example.com/"}
|
@@ -195,6 +306,44 @@ describe JSON::LD::Context do
|
|
195
306
|
}, logger)
|
196
307
|
end
|
197
308
|
|
309
|
+
it "maps term with blank node @id (with deprecation)" do
|
310
|
+
expect do
|
311
|
+
expect(subject.parse({
|
312
|
+
"foo" => {"@id" => "_:bn"}
|
313
|
+
}).send(:mappings)).to produce({
|
314
|
+
"foo" => RDF::Node("bn")
|
315
|
+
}, logger)
|
316
|
+
end.to write("[DEPRECATION]").to(:error)
|
317
|
+
end
|
318
|
+
|
319
|
+
it "warns and ignores keyword-like term" do
|
320
|
+
expect do
|
321
|
+
expect(subject.parse({
|
322
|
+
"@foo" => {"@id" => "http://example.org/foo"}
|
323
|
+
}).send(:mappings)).to produce({}, logger)
|
324
|
+
end.to write("Terms beginning with '@' are reserved").to(:error)
|
325
|
+
end
|
326
|
+
|
327
|
+
it "maps '@' as a term" do
|
328
|
+
expect do
|
329
|
+
expect(subject.parse({
|
330
|
+
"@" => {"@id" => "http://example.org/@"}
|
331
|
+
}).send(:mappings)).to produce({
|
332
|
+
"@" => "http://example.org/@"
|
333
|
+
}, logger)
|
334
|
+
end.not_to write.to(:error)
|
335
|
+
end
|
336
|
+
|
337
|
+
it "maps '@foo.bar' as a term" do
|
338
|
+
expect do
|
339
|
+
expect(subject.parse({
|
340
|
+
"@foo.bar" => {"@id" => "http://example.org/foo.bar"}
|
341
|
+
}).send(:mappings)).to produce({
|
342
|
+
"@foo.bar" => "http://example.org/foo.bar"
|
343
|
+
}, logger)
|
344
|
+
end.not_to write.to(:error)
|
345
|
+
end
|
346
|
+
|
198
347
|
it "associates @list container mapping with term" do
|
199
348
|
expect(subject.parse({
|
200
349
|
"foo" => {"@id" => "http://example.com/", "@container" => "@list"}
|
@@ -227,6 +376,14 @@ describe JSON::LD::Context do
|
|
227
376
|
}, logger)
|
228
377
|
end
|
229
378
|
|
379
|
+
it "associates @json type mapping with term" do
|
380
|
+
expect(subject.parse({
|
381
|
+
"foo" => {"@id" => "http://example.com/", "@type" => "@json"}
|
382
|
+
}).coercions).to produce({
|
383
|
+
"foo" => "@json"
|
384
|
+
}, logger)
|
385
|
+
end
|
386
|
+
|
230
387
|
it "associates type mapping with term" do
|
231
388
|
expect(subject.parse({
|
232
389
|
"foo" => {"@id" => "http://example.com/", "@type" => RDF::XSD.string.to_s}
|
@@ -310,6 +467,29 @@ describe JSON::LD::Context do
|
|
310
467
|
expect(subject.parse({"name" => nil}).send(:mapping, "name")).to be_nil
|
311
468
|
end
|
312
469
|
end
|
470
|
+
|
471
|
+
|
472
|
+
context "@propagate" do
|
473
|
+
it "generates an InvalidPropagateValue error if not a boolean" do
|
474
|
+
expect {subject.parse({'@version' => 1.1, '@propagate' => "String"})}.to raise_error(JSON::LD::JsonLdError::InvalidPropagateValue)
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
context "@import" do
|
479
|
+
before(:each) {JSON::LD::Context::PRELOADED.clear}
|
480
|
+
it "generates an InvalidImportValue error if not a string" do
|
481
|
+
expect {subject.parse({'@version' => 1.1, '@import' => true})}.to raise_error(JSON::LD::JsonLdError::InvalidImportValue)
|
482
|
+
end
|
483
|
+
|
484
|
+
it "retrieves remote context" do
|
485
|
+
expect(JSON::LD::API).to receive(:documentLoader).with("http://example.com/context", anything).and_yield(remote_doc)
|
486
|
+
ec = subject.parse(JSON.parse %({
|
487
|
+
"@version": 1.1,
|
488
|
+
"@import": "http://example.com/context"
|
489
|
+
}))
|
490
|
+
expect(ec.term_definitions).to include("avatar")
|
491
|
+
end
|
492
|
+
end
|
313
493
|
end
|
314
494
|
|
315
495
|
describe "Syntax Errors" do
|
@@ -323,16 +503,28 @@ describe JSON::LD::Context do
|
|
323
503
|
"@type as object" => {"foo" => {"@type" => {}}},
|
324
504
|
"@type as array" => {"foo" => {"@type" => []}},
|
325
505
|
"@type as @list" => {"foo" => {"@type" => "@list"}},
|
506
|
+
"@type as @none" => {"@version": 1.1, "foo" => {"@type" => "@none"}},
|
326
507
|
"@type as @set" => {"foo" => {"@type" => "@set"}},
|
327
508
|
"@container as object" => {"foo" => {"@container" => {}}},
|
328
509
|
"@container as empty array" => {"foo" => {"@container" => []}},
|
329
510
|
"@container as string" => {"foo" => {"@container" => "true"}},
|
330
511
|
"@context which is invalid" => {"foo" => {"@context" => {"bar" => []}}},
|
331
512
|
"@language as @id" => {"@language" => {"@id" => "http://example.com/"}},
|
513
|
+
"@direction as foo" => {"@direction" => "foo"},
|
332
514
|
"@vocab as @id" => {"@vocab" => {"@id" => "http://example.com/"}},
|
333
515
|
"@prefix string" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => "str"}},
|
334
516
|
"@prefix array" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => []}},
|
335
517
|
"@prefix object" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => {}}},
|
518
|
+
"IRI term expands to different IRI" => {
|
519
|
+
"ex" => "http://example.com/",
|
520
|
+
"ex2" => "http://example.com/2/",
|
521
|
+
"ex:foo" => "ex2:foo"
|
522
|
+
},
|
523
|
+
"IRI term expands to different IRI (reverse)" => {
|
524
|
+
"ex" => "http://example.com/",
|
525
|
+
"ex2" => "http://example.com/2/",
|
526
|
+
"ex:foo" => {"@reverse" => "ex2:foo"}
|
527
|
+
}
|
336
528
|
}.each do |title, context|
|
337
529
|
it title do
|
338
530
|
expect {
|
@@ -343,12 +535,14 @@ describe JSON::LD::Context do
|
|
343
535
|
end
|
344
536
|
|
345
537
|
context "1.0" do
|
346
|
-
let(:context) {JSON::LD::Context.new(logger: logger, validate: true)}
|
538
|
+
let(:context) {JSON::LD::Context.new(logger: logger, validate: true, processingMode: 'json-ld-1.0')}
|
347
539
|
{
|
348
540
|
"@context" => {"foo" => {"@id" => 'http://example.org/', "@context" => {}}},
|
349
541
|
"@container @id" => {"foo" => {"@container" => "@id"}},
|
350
542
|
"@container @type" => {"foo" => {"@container" => "@type"}},
|
351
543
|
"@nest" => {"foo" => {"@id" => 'http://example.org/', "@nest" => "@nest"}},
|
544
|
+
"@type as @none" => {"foo" => {"@type" => "@none"}},
|
545
|
+
"@type as @json" => {"foo" => {"@type" => "@json"}},
|
352
546
|
"@prefix" => {"foo" => {"@id" => 'http://example.org/', "@prefix" => true}},
|
353
547
|
}.each do |title, context|
|
354
548
|
it title do
|
@@ -358,9 +552,26 @@ describe JSON::LD::Context do
|
|
358
552
|
}.to raise_error(JSON::LD::JsonLdError)
|
359
553
|
end
|
360
554
|
end
|
555
|
+
|
556
|
+
it "generates InvalidContextMember if using @propagate" do
|
557
|
+
expect {context.parse({'@propagate' => true})}.to raise_error(JSON::LD::JsonLdError::InvalidContextMember)
|
558
|
+
end
|
559
|
+
|
560
|
+
it "generates InvalidContextMember if using @import" do
|
561
|
+
expect {context.parse({'@import' => "location"})}.to raise_error(JSON::LD::JsonLdError::InvalidContextMember)
|
562
|
+
end
|
563
|
+
|
564
|
+
(JSON::LD::KEYWORDS - %w(@base @language @version @protected @propagate @vocab)).each do |kw|
|
565
|
+
it "does not redefine #{kw} with an @container" do
|
566
|
+
expect {
|
567
|
+
ec = subject.parse({kw => {"@container" => "@set"}})
|
568
|
+
expect(ec.serialize).to produce({}, logger)
|
569
|
+
}.to raise_error(JSON::LD::JsonLdError)
|
570
|
+
end
|
571
|
+
end
|
361
572
|
end
|
362
573
|
|
363
|
-
(JSON::LD::KEYWORDS - %w(@base @language @vocab)).each do |kw|
|
574
|
+
(JSON::LD::KEYWORDS - %w(@base @direction @language @protected @propagate @import @version @vocab)).each do |kw|
|
364
575
|
it "does not redefine #{kw} as a string" do
|
365
576
|
expect {
|
366
577
|
ec = subject.parse({kw => "http://example.com/"})
|
@@ -374,6 +585,18 @@ describe JSON::LD::Context do
|
|
374
585
|
expect(ec.serialize).to produce({}, logger)
|
375
586
|
}.to raise_error(JSON::LD::JsonLdError)
|
376
587
|
end
|
588
|
+
|
589
|
+
it "does not redefine #{kw} with an @container" do
|
590
|
+
expect {
|
591
|
+
ec = subject.parse({"@version" => 1.1, kw => {"@container" => "@set"}})
|
592
|
+
expect(ec.serialize).to produce({}, logger)
|
593
|
+
}.to raise_error(JSON::LD::JsonLdError)
|
594
|
+
end unless kw == '@type'
|
595
|
+
|
596
|
+
it "redefines #{kw} with an @container" do
|
597
|
+
ec = subject.parse({kw => {"@container" => "@set"}})
|
598
|
+
expect(ec.as_array('@type')).to be_truthy
|
599
|
+
end if kw == '@type'
|
377
600
|
end
|
378
601
|
end
|
379
602
|
end
|
@@ -609,7 +832,19 @@ describe JSON::LD::Context do
|
|
609
832
|
}, logger)
|
610
833
|
end
|
611
834
|
|
612
|
-
it "
|
835
|
+
it "prefix with @type @json" do
|
836
|
+
expect(subject.parse({
|
837
|
+
"knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"}
|
838
|
+
}).
|
839
|
+
send(:clear_provided_context).
|
840
|
+
serialize).to produce({
|
841
|
+
"@context" => {
|
842
|
+
"knows" => {"@id" => RDF::Vocab::FOAF.knows.to_s, "@type" => "@json"}
|
843
|
+
}
|
844
|
+
}, logger)
|
845
|
+
end
|
846
|
+
|
847
|
+
it "Compact IRI with @type" do
|
613
848
|
expect(subject.parse({
|
614
849
|
"foaf" => RDF::Vocab::FOAF.to_uri.to_s,
|
615
850
|
"foaf:knows" => {
|
@@ -691,7 +926,7 @@ describe JSON::LD::Context do
|
|
691
926
|
}, logger)
|
692
927
|
end
|
693
928
|
|
694
|
-
it "compacts IRIs to
|
929
|
+
it "compacts IRIs to Compact IRIs" do
|
695
930
|
expect(subject.parse({
|
696
931
|
"ex" => 'http://example.org/',
|
697
932
|
"term" => {"@id" => "ex:term", "@type" => "ex:datatype"}
|
@@ -756,6 +991,48 @@ describe JSON::LD::Context do
|
|
756
991
|
end
|
757
992
|
end
|
758
993
|
|
994
|
+
describe "#vocab=" do
|
995
|
+
subject {
|
996
|
+
context.parse({
|
997
|
+
'@base' => 'http://base/resource',
|
998
|
+
})
|
999
|
+
}
|
1000
|
+
|
1001
|
+
it "sets vocab from absolute iri" do
|
1002
|
+
subject.vocab = "http://example.org/"
|
1003
|
+
expect(subject.vocab).to eql RDF::URI("http://example.org/")
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
it "sets vocab from empty string" do
|
1007
|
+
subject.vocab = ""
|
1008
|
+
expect(subject.vocab).to eql RDF::URI("http://base/resource")
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
it "sets vocab to blank node (with deprecation)" do
|
1012
|
+
expect do
|
1013
|
+
subject.vocab = "_:bn"
|
1014
|
+
end.to write("[DEPRECATION]").to(:error)
|
1015
|
+
expect(subject.vocab).to eql "_:bn"
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
it "sets vocab from relative IRI" do
|
1019
|
+
subject.vocab = "relative#"
|
1020
|
+
expect(subject.vocab).to eql RDF::URI("http://base/relative#")
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
it "sets vocab from relative IRI given an existing vocab" do
|
1024
|
+
subject.vocab = "http://example.org/."
|
1025
|
+
subject.vocab = "relative#"
|
1026
|
+
expect(subject.vocab).to eql RDF::URI("http://example.org/.relative#")
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
it "sets vocab from relative IRI given an existing vocab which is also relative" do
|
1030
|
+
subject.vocab = "/rel1"
|
1031
|
+
subject.vocab = "rel2#"
|
1032
|
+
expect(subject.vocab).to eql RDF::URI("http://base/rel1rel2#")
|
1033
|
+
end
|
1034
|
+
end
|
1035
|
+
|
759
1036
|
describe "#expand_iri" do
|
760
1037
|
subject {
|
761
1038
|
context.parse({
|
@@ -786,17 +1063,19 @@ describe JSON::LD::Context do
|
|
786
1063
|
"absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")],
|
787
1064
|
"term" => ["ex", RDF::URI("ex")],
|
788
1065
|
"prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")],
|
1066
|
+
"#frag" => ["#frag", RDF::URI("#frag")],
|
1067
|
+
"#frag:2" => ["#frag:2", RDF::URI("#frag:2")],
|
789
1068
|
"keyword" => ["@type", "@type"],
|
790
|
-
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
791
1069
|
"unmapped" => ["foo", RDF::URI("foo")],
|
792
1070
|
"relative" => ["foo/bar", RDF::URI("foo/bar")],
|
793
1071
|
"dotseg" => ["../foo/bar", RDF::URI("../foo/bar")],
|
794
1072
|
"empty term" => ["", RDF::URI("")],
|
795
1073
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
796
|
-
"absolute IRI looking like a
|
1074
|
+
"absolute IRI looking like a Compact IRI" =>
|
797
1075
|
["foo:bar", RDF::URI("foo:bar")],
|
798
1076
|
"bnode" => ["_:t0", RDF::Node("t0")],
|
799
1077
|
"_" => ["_", RDF::URI("_")],
|
1078
|
+
"@" => ["@", RDF::URI("@")],
|
800
1079
|
}.each do |title, (input, result)|
|
801
1080
|
it title do
|
802
1081
|
expect(subject.expand_iri(input)).to produce(result, logger)
|
@@ -809,17 +1088,19 @@ describe JSON::LD::Context do
|
|
809
1088
|
"absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")],
|
810
1089
|
"term" => ["ex", RDF::URI("http://base/ex")],
|
811
1090
|
"prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")],
|
1091
|
+
"#frag" => ["#frag", RDF::URI("http://base/base#frag")],
|
1092
|
+
"#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")],
|
812
1093
|
"keyword" => ["@type", "@type"],
|
813
|
-
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
814
1094
|
"unmapped" => ["foo", RDF::URI("http://base/foo")],
|
815
1095
|
"relative" => ["foo/bar", RDF::URI("http://base/foo/bar")],
|
816
1096
|
"dotseg" => ["../foo/bar", RDF::URI("http://base/foo/bar")],
|
817
1097
|
"empty term" => ["", RDF::URI("http://base/base")],
|
818
1098
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
819
|
-
"absolute IRI looking like a
|
1099
|
+
"absolute IRI looking like a compact IRI" =>
|
820
1100
|
["foo:bar", RDF::URI("foo:bar")],
|
821
1101
|
"bnode" => ["_:t0", RDF::Node("t0")],
|
822
1102
|
"_" => ["_", RDF::URI("http://base/_")],
|
1103
|
+
"@" => ["@", RDF::URI("http://base/@")],
|
823
1104
|
}.each do |title, (input, result)|
|
824
1105
|
it title do
|
825
1106
|
expect(subject.expand_iri(input, documentRelative: true)).to produce(result, logger)
|
@@ -832,17 +1113,19 @@ describe JSON::LD::Context do
|
|
832
1113
|
"absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")],
|
833
1114
|
"term" => ["ex", RDF::URI("http://example.org/")],
|
834
1115
|
"prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")],
|
1116
|
+
"#frag" => ["#frag", RDF::URI("http://vocab/#frag")],
|
1117
|
+
"#frag:2" => ["#frag:2", RDF::URI("http://vocab/#frag:2")],
|
835
1118
|
"keyword" => ["@type", "@type"],
|
836
|
-
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
837
1119
|
"unmapped" => ["foo", RDF::URI("http://vocab/foo")],
|
838
1120
|
"relative" => ["foo/bar", RDF::URI("http://vocab/foo/bar")],
|
839
1121
|
"dotseg" => ["../foo/bar", RDF::URI("http://vocab/../foo/bar")],
|
840
1122
|
"empty term" => ["", RDF::URI("http://empty/")],
|
841
1123
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
842
|
-
"absolute IRI looking like a
|
1124
|
+
"absolute IRI looking like a compact IRI" =>
|
843
1125
|
["foo:bar", RDF::URI("foo:bar")],
|
844
1126
|
"bnode" => ["_:t0", RDF::Node("t0")],
|
845
1127
|
"_" => ["_", RDF::URI("http://underscore/")],
|
1128
|
+
"@" => ["@", RDF::URI("http://vocab/@")],
|
846
1129
|
}.each do |title, (input, result)|
|
847
1130
|
it title do
|
848
1131
|
expect(subject.expand_iri(input, vocab: true)).to produce(result, logger)
|
@@ -864,14 +1147,15 @@ describe JSON::LD::Context do
|
|
864
1147
|
"absolute IRI" => ["http://example.org/", RDF::URI("http://example.org/")],
|
865
1148
|
"term" => ["ex", RDF::URI("http://example.org/")],
|
866
1149
|
"prefix:suffix" => ["ex:suffix", RDF::URI("http://example.org/suffix")],
|
1150
|
+
"#frag" => ["#frag", RDF::URI("http://base/base#frag")],
|
1151
|
+
"#frag:2" => ["#frag:2", RDF::URI("http://base/base#frag:2")],
|
867
1152
|
"keyword" => ["@type", "@type"],
|
868
|
-
"empty" => [":suffix", RDF::URI("http://empty/suffix")],
|
869
1153
|
"unmapped" => ["foo", RDF::URI("http://base/basefoo")],
|
870
1154
|
"relative" => ["foo/bar", RDF::URI("http://base/basefoo/bar")],
|
871
1155
|
"dotseg" => ["../foo/bar", RDF::URI("http://base/base../foo/bar")],
|
872
1156
|
"empty term" => ["", RDF::URI("http://empty/")],
|
873
1157
|
"another abs IRI"=>["ex://foo", RDF::URI("ex://foo")],
|
874
|
-
"absolute IRI looking like a
|
1158
|
+
"absolute IRI looking like a compact IRI" =>
|
875
1159
|
["foo:bar", RDF::URI("foo:bar")],
|
876
1160
|
"bnode" => ["_:t0", RDF::Node("t0")],
|
877
1161
|
"_" => ["_", RDF::URI("http://underscore/")],
|
@@ -881,6 +1165,14 @@ describe JSON::LD::Context do
|
|
881
1165
|
end
|
882
1166
|
end
|
883
1167
|
end
|
1168
|
+
|
1169
|
+
it "expand-0110" do
|
1170
|
+
ctx = JSON::LD::Context.parse({
|
1171
|
+
"@base" => "http://example.com/some/deep/directory/and/file/",
|
1172
|
+
"@vocab" => "/relative"
|
1173
|
+
})
|
1174
|
+
expect(ctx.expand_iri("#fragment-works", vocab: true)).to produce("http://example.com/relative#fragment-works", logger)
|
1175
|
+
end
|
884
1176
|
end
|
885
1177
|
end
|
886
1178
|
end
|
@@ -897,7 +1189,7 @@ describe JSON::LD::Context do
|
|
897
1189
|
'lex' => {'@id' => 'ex', '@language' => 'en'},
|
898
1190
|
'tex' => {'@id' => 'ex', '@type' => 'xsd:string'},
|
899
1191
|
'exp' => {'@id' => 'ex:pert'},
|
900
|
-
'experts' => {'@id' => 'ex:perts'}
|
1192
|
+
'experts' => {'@id' => 'ex:perts'},
|
901
1193
|
})
|
902
1194
|
logger.clear
|
903
1195
|
c
|
@@ -908,14 +1200,17 @@ describe JSON::LD::Context do
|
|
908
1200
|
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
909
1201
|
"prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
|
910
1202
|
"keyword" => ["@type", "@type"],
|
911
|
-
"empty" => [":suffix", "http://empty/suffix"],
|
912
1203
|
"unmapped" => ["foo", "foo"],
|
913
|
-
"bnode" => [
|
1204
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
914
1205
|
"relative" => ["foo/bar", "http://base/foo/bar"],
|
915
|
-
"odd
|
1206
|
+
"odd Compact IRI"=>["ex:perts", "http://example.org/perts"]
|
916
1207
|
}.each do |title, (result, input)|
|
917
1208
|
it title do
|
918
|
-
|
1209
|
+
if result.is_a?(Class)
|
1210
|
+
expect {subject.compact_iri(input)}.to raise_error(result)
|
1211
|
+
else
|
1212
|
+
expect(subject.compact_iri(input)).to produce(result, logger)
|
1213
|
+
end
|
919
1214
|
end
|
920
1215
|
end
|
921
1216
|
|
@@ -924,14 +1219,17 @@ describe JSON::LD::Context do
|
|
924
1219
|
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
925
1220
|
"prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
|
926
1221
|
"keyword" => ["@type", "@type"],
|
927
|
-
"empty" => [":suffix", "http://empty/suffix"],
|
928
1222
|
"unmapped" => ["foo", "foo"],
|
929
|
-
"bnode" => [
|
1223
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
930
1224
|
"relative" => ["http://base/foo/bar", "http://base/foo/bar"],
|
931
|
-
"odd
|
1225
|
+
"odd Compact IRI"=> ["experts", "http://example.org/perts"]
|
932
1226
|
}.each do |title, (result, input)|
|
933
1227
|
it title do
|
934
|
-
|
1228
|
+
if result.is_a?(Class)
|
1229
|
+
expect {subject.compact_iri(input, vocab: true)}.to raise_error(result)
|
1230
|
+
else
|
1231
|
+
expect(subject.compact_iri(input, vocab: true)).to produce(result, logger)
|
1232
|
+
end
|
935
1233
|
end
|
936
1234
|
end
|
937
1235
|
end
|
@@ -943,14 +1241,17 @@ describe JSON::LD::Context do
|
|
943
1241
|
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
944
1242
|
"prefix:suffix" => ["suffix", "http://example.org/suffix"],
|
945
1243
|
"keyword" => ["@type", "@type"],
|
946
|
-
"empty" => [":suffix", "http://empty/suffix"],
|
947
1244
|
"unmapped" => ["foo", "foo"],
|
948
|
-
"bnode" => [
|
1245
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
949
1246
|
"relative" => ["http://base/foo/bar", "http://base/foo/bar"],
|
950
|
-
"odd
|
1247
|
+
"odd Compact IRI"=> ["experts", "http://example.org/perts"]
|
951
1248
|
}.each do |title, (result, input)|
|
952
1249
|
it title do
|
953
|
-
|
1250
|
+
if result.is_a?(Class)
|
1251
|
+
expect {subject.compact_iri(input, vocab: true)}.to raise_error(result)
|
1252
|
+
else
|
1253
|
+
expect(subject.compact_iri(input, vocab: true)).to produce(result, logger)
|
1254
|
+
end
|
954
1255
|
end
|
955
1256
|
end
|
956
1257
|
|
@@ -963,7 +1264,7 @@ describe JSON::LD::Context do
|
|
963
1264
|
|
964
1265
|
context "with @vocab: relative" do
|
965
1266
|
before(:each) {
|
966
|
-
subject.vocab =
|
1267
|
+
subject.vocab = nil
|
967
1268
|
subject.base = 'http://base/base'
|
968
1269
|
}
|
969
1270
|
|
@@ -971,14 +1272,17 @@ describe JSON::LD::Context do
|
|
971
1272
|
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
972
1273
|
"prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
|
973
1274
|
"keyword" => ["@type", "@type"],
|
974
|
-
"empty" => [":suffix", "http://empty/suffix"],
|
975
1275
|
"unmapped" => ["foo", "foo"],
|
976
|
-
"bnode" => [
|
977
|
-
"relative" => ["foo/bar",
|
978
|
-
"odd
|
1276
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
1277
|
+
"relative" => ["http://base/foo/bar", "http://base/foo/bar"],
|
1278
|
+
"odd Compact IRI"=> ["experts", "http://example.org/perts"]
|
979
1279
|
}.each do |title, (result, input)|
|
980
1280
|
it title do
|
981
|
-
|
1281
|
+
if result.is_a?(Class)
|
1282
|
+
expect {subject.compact_iri(input, vocab: true)}.to raise_error(result)
|
1283
|
+
else
|
1284
|
+
expect(subject.compact_iri(input, vocab: true)).to produce(result, logger)
|
1285
|
+
end
|
982
1286
|
end
|
983
1287
|
end
|
984
1288
|
end
|
@@ -990,12 +1294,15 @@ describe JSON::LD::Context do
|
|
990
1294
|
"xsd" => RDF::XSD.to_s,
|
991
1295
|
"plain" => "http://example.com/plain",
|
992
1296
|
"lang" => {"@id" => "http://example.com/lang", "@language" => "en"},
|
1297
|
+
"dir" => {"@id" => "http://example.com/dir", "@direction" => "ltr"},
|
1298
|
+
"langdir" => {"@id" => "http://example.com/langdir", "@language" => "en", "@direction" => "ltr"},
|
993
1299
|
"bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean"},
|
994
1300
|
"integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer"},
|
995
1301
|
"double" => {"@id" => "http://example.com/double", "@type" => "xsd:double"},
|
996
1302
|
"date" => {"@id" => "http://example.com/date", "@type" => "xsd:date"},
|
997
1303
|
"id" => {"@id" => "http://example.com/id", "@type" => "@id"},
|
998
1304
|
'graph' => {'@id' => 'http://example.com/graph', '@container' => '@graph'},
|
1305
|
+
'json' => {'@id' => 'http://example.com/json', '@type' => '@json'},
|
999
1306
|
|
1000
1307
|
"list_plain" => {"@id" => "http://example.com/plain", "@container" => "@list"},
|
1001
1308
|
"list_lang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@list"},
|
@@ -1031,6 +1338,9 @@ describe JSON::LD::Context do
|
|
1031
1338
|
"set_integer" => [{"@value" => "1", "@type" => "http://www.w3.org/2001/XMLSchema#integer"}],
|
1032
1339
|
"set_id" => [{"@id" => "http://example.org/id"}],
|
1033
1340
|
"graph" => [{"@graph" => [{"@id" => "http://example.org/id"}]}],
|
1341
|
+
'json' => [{"@value" => {"some" => "json"}, "@type" => "@json"}],
|
1342
|
+
'dir' => [{"@value" => "dir", "@direction" => "ltr"}],
|
1343
|
+
'langdir' => [{"@value" => "lang dir", "@language" => "en", "@direction" => "ltr"}],
|
1034
1344
|
}.each do |prop, values|
|
1035
1345
|
context "uses #{prop}" do
|
1036
1346
|
values.each do |value|
|
@@ -1074,7 +1384,7 @@ describe JSON::LD::Context do
|
|
1074
1384
|
end
|
1075
1385
|
end
|
1076
1386
|
|
1077
|
-
context "
|
1387
|
+
context "Compact IRI compaction" do
|
1078
1388
|
{
|
1079
1389
|
"nil" => [nil, nil],
|
1080
1390
|
"absolute IRI" => ["http://example.com/", "http://example.com/"],
|
@@ -1082,12 +1392,16 @@ describe JSON::LD::Context do
|
|
1082
1392
|
"keyword" => ["@type", "@type"],
|
1083
1393
|
"empty" => [":suffix", "http://empty/suffix"],
|
1084
1394
|
"unmapped" => ["foo", "foo"],
|
1085
|
-
"bnode" => [
|
1395
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
1086
1396
|
"relative" => ["foo/bar", "http://base/foo/bar"],
|
1087
|
-
"odd
|
1397
|
+
"odd Compact IRI"=> ["ex:perts", "http://example.org/perts"]
|
1088
1398
|
}.each do |title, (result, input)|
|
1089
1399
|
it title do
|
1090
|
-
|
1400
|
+
if result.is_a?(Class)
|
1401
|
+
expect {subject.compact_iri(input)}.to raise_error(result)
|
1402
|
+
else
|
1403
|
+
expect(subject.compact_iri(input)).to produce(result, logger)
|
1404
|
+
end
|
1091
1405
|
end
|
1092
1406
|
end
|
1093
1407
|
|
@@ -1100,12 +1414,16 @@ describe JSON::LD::Context do
|
|
1100
1414
|
"keyword" => ["@type", "@type"],
|
1101
1415
|
"empty" => [":suffix", "http://empty/suffix"],
|
1102
1416
|
"unmapped" => ["foo", "foo"],
|
1103
|
-
"bnode" => [
|
1417
|
+
"bnode" => [JSON::LD::JsonLdError:: IRIConfusedWithPrefix, RDF::Node("a")],
|
1104
1418
|
"relative" => ["http://base/foo/bar", "http://base/foo/bar"],
|
1105
|
-
"odd
|
1419
|
+
"odd Compact IRI"=> ["experts", "http://example.org/perts"]
|
1106
1420
|
}.each do |title, (result, input)|
|
1107
1421
|
it title do
|
1108
|
-
|
1422
|
+
if result.is_a?(Class)
|
1423
|
+
expect {subject.compact_iri(input, vocab: true)}.to raise_error(result)
|
1424
|
+
else
|
1425
|
+
expect(subject.compact_iri(input, vocab: true)).to produce(result, logger)
|
1426
|
+
end
|
1109
1427
|
end
|
1110
1428
|
end
|
1111
1429
|
end
|
@@ -1256,6 +1574,8 @@ describe JSON::LD::Context do
|
|
1256
1574
|
"ex:integer" => {"@type" => "xsd:integer"},
|
1257
1575
|
"ex:double" => {"@type" => "xsd:double"},
|
1258
1576
|
"ex:boolean" => {"@type" => "xsd:boolean"},
|
1577
|
+
"ex:none" => {"@type" => "@none"},
|
1578
|
+
"ex:json" => {"@type" => "@json"}
|
1259
1579
|
})
|
1260
1580
|
logger.clear
|
1261
1581
|
ctx
|
@@ -1280,7 +1600,6 @@ describe JSON::LD::Context do
|
|
1280
1600
|
"native integer" => ["foo", 1, {"@value" => 1}],
|
1281
1601
|
"native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
|
1282
1602
|
"native date" => ["foo", Date.parse("2011-12-27"), {"@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s}],
|
1283
|
-
"native time" => ["foo", Time.parse("10:11:12Z"), {"@value" => "10:11:12Z", "@type" => RDF::XSD.time.to_s}],
|
1284
1603
|
"native dateTime" =>["foo", DateTime.parse("2011-12-27T10:11:12Z"), {"@value" => "2011-12-27T10:11:12Z", "@type" => RDF::XSD.dateTime.to_s}],
|
1285
1604
|
"rdf boolean" => ["foo", RDF::Literal(true), {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
|
1286
1605
|
"rdf integer" => ["foo", RDF::Literal(1), {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
|
@@ -1289,7 +1608,17 @@ describe JSON::LD::Context do
|
|
1289
1608
|
"rdf URI" => ["foo", RDF::URI("foo"), {"@id" => "foo"}],
|
1290
1609
|
"rdf date " => ["foo", RDF::Literal(Date.parse("2011-12-27")), {"@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s}],
|
1291
1610
|
"rdf nonNeg" => ["foo", RDF::Literal::NonNegativeInteger.new(1), {"@value" => "1", "@type" => RDF::XSD.nonNegativeInteger}],
|
1292
|
-
"rdf float" => ["foo", RDF::Literal::Float.new(1.0),
|
1611
|
+
"rdf float" => ["foo", RDF::Literal::Float.new(1.0), {"@value" => "1.0", "@type" => RDF::XSD.float}],
|
1612
|
+
"ex:none string" => ["ex:none", "foo", {"@value" => "foo"}],
|
1613
|
+
"ex:none boolean" =>["ex:none", true, {"@value" => true}],
|
1614
|
+
"ex:none integer" =>["ex:none", 1, {"@value" => 1}],
|
1615
|
+
"ex:none double" => ["ex:none", 1.1e1, {"@value" => 1.1E1}],
|
1616
|
+
"ex:json string" => ["ex:json", "foo", {"@value" => "foo", "@type" => "@json"}],
|
1617
|
+
"ex:json boolean" =>["ex:json", true, {"@value" => true, "@type" => "@json"}],
|
1618
|
+
"ex:json integer" =>["ex:json", 1, {"@value" => 1, "@type" => "@json"}],
|
1619
|
+
"ex:json double" => ["ex:json", 1.1e1, {"@value" => 1.1e1, "@type" => "@json"}],
|
1620
|
+
"ex:json object" => ["ex:json", {"foo" => "bar"}, {"@value" => {"foo" => "bar"}, "@type" => "@json"}],
|
1621
|
+
"ex:json array" => ["ex:json", [{"foo" => "bar"}], {"@value" => [{"foo" => "bar"}], "@type" => "@json"}],
|
1293
1622
|
}.each do |title, (key, compacted, expanded)|
|
1294
1623
|
it title do
|
1295
1624
|
expect(subject.expand_value(key, compacted)).to produce(expanded, logger)
|
@@ -1318,15 +1647,20 @@ describe JSON::LD::Context do
|
|
1318
1647
|
"boolean-boolean" => ["ex:boolean", true, {"@value" => true, "@type" => RDF::XSD.boolean.to_s}],
|
1319
1648
|
"boolean-integer" => ["ex:integer", true, {"@value" => true, "@type" => RDF::XSD.integer.to_s}],
|
1320
1649
|
"boolean-double" => ["ex:double", true, {"@value" => true, "@type" => RDF::XSD.double.to_s}],
|
1650
|
+
"boolean-json" => ["ex:json", true, {"@value" => true, "@type" => '@json'}],
|
1321
1651
|
"double-boolean" => ["ex:boolean", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.boolean.to_s}],
|
1322
1652
|
"double-double" => ["ex:double", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.double.to_s}],
|
1323
1653
|
"double-integer" => ["foaf:age", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.integer.to_s}],
|
1654
|
+
"double-json" => ["ex:json", 1.1, {"@value" => 1.1, "@type" => '@json'}],
|
1655
|
+
"json-json" => ["ex:json", {"foo" => "bar"}, {"@value" => {"foo" => "bar"}, "@type" => '@json'}],
|
1324
1656
|
"integer-boolean" => ["ex:boolean", 1, {"@value" => 1, "@type" => RDF::XSD.boolean.to_s}],
|
1325
1657
|
"integer-double" => ["ex:double", 1, {"@value" => 1, "@type" => RDF::XSD.double.to_s}],
|
1326
1658
|
"integer-integer" => ["foaf:age", 1, {"@value" => 1, "@type" => RDF::XSD.integer.to_s}],
|
1659
|
+
"integer-json" => ["ex:json", 1, {"@value" => 1, "@type" => '@json'}],
|
1327
1660
|
"string-boolean" => ["ex:boolean", "foo", {"@value" => "foo", "@type" => RDF::XSD.boolean.to_s}],
|
1328
1661
|
"string-double" => ["ex:double", "foo", {"@value" => "foo", "@type" => RDF::XSD.double.to_s}],
|
1329
1662
|
"string-integer" => ["foaf:age", "foo", {"@value" => "foo", "@type" => RDF::XSD.integer.to_s}],
|
1663
|
+
"string-json" => ["ex:json", "foo", {"@value" => "foo", "@type" => '@json'}],
|
1330
1664
|
}.each do |title, (key, compacted, expanded)|
|
1331
1665
|
it title do
|
1332
1666
|
expect(subject.expand_value(key, compacted)).to produce(expanded, logger)
|
@@ -1348,6 +1682,7 @@ describe JSON::LD::Context do
|
|
1348
1682
|
"dc:created" => {"@type" => RDF::XSD.date.to_s},
|
1349
1683
|
"foaf:age" => {"@type" => RDF::XSD.integer.to_s},
|
1350
1684
|
"foaf:knows" => {"@type" => "@id"},
|
1685
|
+
"ex:none" => {"@type" => "@none"},
|
1351
1686
|
})
|
1352
1687
|
logger.clear
|
1353
1688
|
c
|
@@ -1360,16 +1695,19 @@ describe JSON::LD::Context do
|
|
1360
1695
|
"integer" => ["foaf:age", "54", {"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
|
1361
1696
|
"date " => ["dc:created", "2011-12-27Z", {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
|
1362
1697
|
"no IRI" => ["foo", {"@id" =>"http://example.com/"},{"@id" => "http://example.com/"}],
|
1363
|
-
"no IRI (
|
1364
|
-
"no boolean" => ["foo", {"@value" => "true", "@type" =>
|
1365
|
-
"no integer" => ["foo", {"@value" => "54", "@type" =>
|
1366
|
-
"no date " => ["foo", {"@value" => "2011-12-27Z", "@type" =>
|
1698
|
+
"no IRI (Compact IRI)" => ["foo", {"@id" => RDF::Vocab::FOAF.Person.to_s}, {"@id" => RDF::Vocab::FOAF.Person.to_s}],
|
1699
|
+
"no boolean" => ["foo", {"@value" => "true", "@type" => "xsd:boolean"},{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
|
1700
|
+
"no integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"},{"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
|
1701
|
+
"no date " => ["foo", {"@value" => "2011-12-27Z", "@type" => "xsd:date"}, {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
|
1367
1702
|
"no string " => ["foo", "string", {"@value" => "string"}],
|
1368
1703
|
"no lang " => ["nolang", "string", {"@value" => "string"}],
|
1369
1704
|
"native boolean" => ["foo", true, {"@value" => true}],
|
1370
1705
|
"native integer" => ["foo", 1, {"@value" => 1}],
|
1371
1706
|
"native integer(list)"=>["list", 1, {"@value" => 1}],
|
1372
1707
|
"native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
|
1708
|
+
"ex:none IRI" => ["ex:none", {"@id" => "http://example.com/"}, {"@id" => "http://example.com/"}],
|
1709
|
+
"ex:none string" => ["ex:none", {"@value" => "string"}, {"@value" => "string"}],
|
1710
|
+
"ex:none integer" =>["ex:none", {"@value" => "54", "@type" => "xsd:integer"}, {"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
|
1373
1711
|
}.each do |title, (key, compacted, expanded)|
|
1374
1712
|
it title do
|
1375
1713
|
expect(subject.compact_value(key, expanded)).to produce(compacted, logger)
|
@@ -1379,8 +1717,8 @@ describe JSON::LD::Context do
|
|
1379
1717
|
context "@language" do
|
1380
1718
|
{
|
1381
1719
|
"@id" => ["foo", {"@id" => "foo"}, {"@id" => "foo"}],
|
1382
|
-
"integer" => ["foo", {"@value" => "54", "@type" =>
|
1383
|
-
"date" => ["foo", {"@value" => "2011-12-27Z","@type" =>
|
1720
|
+
"integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"}, {"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
|
1721
|
+
"date" => ["foo", {"@value" => "2011-12-27Z","@type" => "xsd:date"},{"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
|
1384
1722
|
"no lang" => ["foo", {"@value" => "foo" }, {"@value" => "foo"}],
|
1385
1723
|
"same lang" => ["foo", "foo", {"@value" => "foo", "@language" => "en"}],
|
1386
1724
|
"other lang" => ["foo", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
|
@@ -1630,6 +1968,62 @@ describe JSON::LD::Context do
|
|
1630
1968
|
end
|
1631
1969
|
end
|
1632
1970
|
|
1971
|
+
describe "protected contexts" do
|
1972
|
+
it "seals a term with @protected true" do
|
1973
|
+
ctx = context.parse({
|
1974
|
+
"protected" => {"@id" => "http://example.com/protected", "@protected" => true},
|
1975
|
+
"unprotected" => {"@id" => "http://example.com/unprotected"},
|
1976
|
+
})
|
1977
|
+
expect(ctx.term_definitions["protected"]).to be_protected
|
1978
|
+
expect(ctx.term_definitions["unprotected"]).not_to be_protected
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
it "seals all term with @protected true in context" do
|
1982
|
+
ctx = context.parse({
|
1983
|
+
"@protected" => true,
|
1984
|
+
"protected" => {"@id" => "http://example.com/protected"},
|
1985
|
+
"protected2" => {"@id" => "http://example.com/protected2"},
|
1986
|
+
})
|
1987
|
+
expect(ctx.term_definitions["protected"]).to be_protected
|
1988
|
+
expect(ctx.term_definitions["protected2"]).to be_protected
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
it "does not seal term with @protected: false when context is protected" do
|
1992
|
+
ctx = context.parse({
|
1993
|
+
"@protected" => true,
|
1994
|
+
"protected" => {"@id" => "http://example.com/protected"},
|
1995
|
+
"unprotected" => {"@id" => "http://example.com/unprotected", "@protected" => false},
|
1996
|
+
})
|
1997
|
+
expect(ctx.term_definitions["protected"]).to be_protected
|
1998
|
+
expect(ctx.term_definitions["unprotected"]).not_to be_protected
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
it "does not error when redefining an identical term" do
|
2002
|
+
c = {
|
2003
|
+
"protected" => {"@id" => "http://example.com/protected", "@protected" => true}
|
2004
|
+
}
|
2005
|
+
ctx = context.parse(c)
|
2006
|
+
|
2007
|
+
expect {ctx.parse(c)}.not_to raise_error
|
2008
|
+
end
|
2009
|
+
|
2010
|
+
it "errors when redefining a protected term" do
|
2011
|
+
ctx = context.parse({
|
2012
|
+
"protected" => {"@id" => "http://example.com/protected", "@protected" => true}
|
2013
|
+
})
|
2014
|
+
|
2015
|
+
expect {ctx.parse({"protected" => "http://example.com/different"})}.to raise_error(JSON::LD::JsonLdError::ProtectedTermRedefinition)
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
it "errors when clearing a context having protected terms" do
|
2019
|
+
ctx = context.parse({
|
2020
|
+
"protected" => {"@id" => "http://example.com/protected", "@protected" => true}
|
2021
|
+
})
|
2022
|
+
|
2023
|
+
expect {ctx.parse(nil)}.to raise_error(JSON::LD::JsonLdError::InvalidContextNullification)
|
2024
|
+
end
|
2025
|
+
end
|
2026
|
+
|
1633
2027
|
describe JSON::LD::Context::TermDefinition do
|
1634
2028
|
context "with nothing" do
|
1635
2029
|
subject {described_class.new("term")}
|