json-ld 3.2.3 → 3.2.5

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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/json/ld/api.rb +807 -764
  4. data/lib/json/ld/compact.rb +304 -304
  5. data/lib/json/ld/conneg.rb +179 -161
  6. data/lib/json/ld/context.rb +2080 -1945
  7. data/lib/json/ld/expand.rb +745 -666
  8. data/lib/json/ld/extensions.rb +14 -13
  9. data/lib/json/ld/flatten.rb +257 -247
  10. data/lib/json/ld/format.rb +202 -194
  11. data/lib/json/ld/frame.rb +525 -502
  12. data/lib/json/ld/from_rdf.rb +224 -166
  13. data/lib/json/ld/html/nokogiri.rb +123 -121
  14. data/lib/json/ld/html/rexml.rb +151 -147
  15. data/lib/json/ld/reader.rb +107 -100
  16. data/lib/json/ld/resource.rb +224 -205
  17. data/lib/json/ld/streaming_reader.rb +574 -507
  18. data/lib/json/ld/streaming_writer.rb +93 -92
  19. data/lib/json/ld/to_rdf.rb +171 -167
  20. data/lib/json/ld/utils.rb +270 -264
  21. data/lib/json/ld/version.rb +24 -14
  22. data/lib/json/ld/writer.rb +334 -311
  23. data/lib/json/ld.rb +103 -96
  24. metadata +78 -209
  25. data/spec/api_spec.rb +0 -132
  26. data/spec/compact_spec.rb +0 -3482
  27. data/spec/conneg_spec.rb +0 -373
  28. data/spec/context_spec.rb +0 -2036
  29. data/spec/expand_spec.rb +0 -4496
  30. data/spec/flatten_spec.rb +0 -1203
  31. data/spec/format_spec.rb +0 -115
  32. data/spec/frame_spec.rb +0 -2498
  33. data/spec/from_rdf_spec.rb +0 -1005
  34. data/spec/matchers.rb +0 -20
  35. data/spec/rdfstar_spec.rb +0 -25
  36. data/spec/reader_spec.rb +0 -883
  37. data/spec/resource_spec.rb +0 -76
  38. data/spec/spec_helper.rb +0 -281
  39. data/spec/streaming_reader_spec.rb +0 -237
  40. data/spec/streaming_writer_spec.rb +0 -145
  41. data/spec/suite_compact_spec.rb +0 -22
  42. data/spec/suite_expand_spec.rb +0 -36
  43. data/spec/suite_flatten_spec.rb +0 -34
  44. data/spec/suite_frame_spec.rb +0 -29
  45. data/spec/suite_from_rdf_spec.rb +0 -22
  46. data/spec/suite_helper.rb +0 -411
  47. data/spec/suite_html_spec.rb +0 -22
  48. data/spec/suite_http_spec.rb +0 -35
  49. data/spec/suite_remote_doc_spec.rb +0 -22
  50. data/spec/suite_to_rdf_spec.rb +0 -30
  51. data/spec/support/extensions.rb +0 -44
  52. data/spec/test-files/test-1-compacted.jsonld +0 -10
  53. data/spec/test-files/test-1-context.jsonld +0 -7
  54. data/spec/test-files/test-1-expanded.jsonld +0 -5
  55. data/spec/test-files/test-1-input.jsonld +0 -10
  56. data/spec/test-files/test-1-rdf.ttl +0 -8
  57. data/spec/test-files/test-2-compacted.jsonld +0 -20
  58. data/spec/test-files/test-2-context.jsonld +0 -7
  59. data/spec/test-files/test-2-expanded.jsonld +0 -16
  60. data/spec/test-files/test-2-input.jsonld +0 -20
  61. data/spec/test-files/test-2-rdf.ttl +0 -14
  62. data/spec/test-files/test-3-compacted.jsonld +0 -11
  63. data/spec/test-files/test-3-context.jsonld +0 -8
  64. data/spec/test-files/test-3-expanded.jsonld +0 -10
  65. data/spec/test-files/test-3-input.jsonld +0 -11
  66. data/spec/test-files/test-3-rdf.ttl +0 -8
  67. data/spec/test-files/test-4-compacted.jsonld +0 -10
  68. data/spec/test-files/test-4-context.jsonld +0 -7
  69. data/spec/test-files/test-4-expanded.jsonld +0 -6
  70. data/spec/test-files/test-4-input.jsonld +0 -10
  71. data/spec/test-files/test-4-rdf.ttl +0 -5
  72. data/spec/test-files/test-5-compacted.jsonld +0 -13
  73. data/spec/test-files/test-5-context.jsonld +0 -7
  74. data/spec/test-files/test-5-expanded.jsonld +0 -9
  75. data/spec/test-files/test-5-input.jsonld +0 -13
  76. data/spec/test-files/test-5-rdf.ttl +0 -7
  77. data/spec/test-files/test-6-compacted.jsonld +0 -10
  78. data/spec/test-files/test-6-context.jsonld +0 -7
  79. data/spec/test-files/test-6-expanded.jsonld +0 -10
  80. data/spec/test-files/test-6-input.jsonld +0 -10
  81. data/spec/test-files/test-6-rdf.ttl +0 -6
  82. data/spec/test-files/test-7-compacted.jsonld +0 -23
  83. data/spec/test-files/test-7-context.jsonld +0 -4
  84. data/spec/test-files/test-7-expanded.jsonld +0 -20
  85. data/spec/test-files/test-7-input.jsonld +0 -23
  86. data/spec/test-files/test-7-rdf.ttl +0 -14
  87. data/spec/test-files/test-8-compacted.jsonld +0 -34
  88. data/spec/test-files/test-8-context.jsonld +0 -11
  89. data/spec/test-files/test-8-expanded.jsonld +0 -24
  90. data/spec/test-files/test-8-frame.jsonld +0 -18
  91. data/spec/test-files/test-8-framed.jsonld +0 -25
  92. data/spec/test-files/test-8-input.jsonld +0 -30
  93. data/spec/test-files/test-8-rdf.ttl +0 -15
  94. data/spec/test-files/test-9-compacted.jsonld +0 -20
  95. data/spec/test-files/test-9-context.jsonld +0 -13
  96. data/spec/test-files/test-9-expanded.jsonld +0 -14
  97. data/spec/test-files/test-9-input.jsonld +0 -12
  98. data/spec/to_rdf_spec.rb +0 -1551
  99. data/spec/writer_spec.rb +0 -427
data/spec/expand_spec.rb DELETED
@@ -1,4496 +0,0 @@
1
- # coding: utf-8
2
- require_relative 'spec_helper'
3
-
4
- describe JSON::LD::API do
5
- let(:logger) {RDF::Spec.logger}
6
-
7
- describe ".expand" do
8
- {
9
- "empty doc": {
10
- input: {},
11
- output: []
12
- },
13
- "@list coercion": {
14
- input: %({
15
- "@context": {
16
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
17
- },
18
- "foo": [{"@value": "bar"}]
19
- }),
20
- output: %([{
21
- "http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
22
- }])
23
- },
24
- "native values in list": {
25
- input: %({
26
- "http://example.com/foo": {"@list": [1, 2]}
27
- }),
28
- output: %([{
29
- "http://example.com/foo": [{"@list": [{"@value": 1}, {"@value": 2}]}]
30
- }])
31
- },
32
- "@graph": {
33
- input: %({
34
- "@context": {"ex": "http://example.com/"},
35
- "@graph": [
36
- {"ex:foo": {"@value": "foo"}},
37
- {"ex:bar": {"@value": "bar"}}
38
- ]
39
- }),
40
- output: %([
41
- {"http://example.com/foo": [{"@value": "foo"}]},
42
- {"http://example.com/bar": [{"@value": "bar"}]}
43
- ])
44
- },
45
- "@graph value (expands to array form)": {
46
- input: %({
47
- "@context": {"ex": "http://example.com/"},
48
- "ex:p": {
49
- "@id": "ex:Sub1",
50
- "@graph": {
51
- "ex:q": "foo"
52
- }
53
- }
54
- }),
55
- output: %([{
56
- "http://example.com/p": [{
57
- "@id": "http://example.com/Sub1",
58
- "@graph": [{
59
- "http://example.com/q": [{"@value": "foo"}]
60
- }]
61
- }]
62
- }])
63
- },
64
- "@type with CURIE": {
65
- input: %({
66
- "@context": {"ex": "http://example.com/"},
67
- "@type": "ex:type"
68
- }),
69
- output: %([
70
- {"@type": ["http://example.com/type"]}
71
- ])
72
- },
73
- "@type with CURIE and muliple values": {
74
- input: %({
75
- "@context": {"ex": "http://example.com/"},
76
- "@type": ["ex:type1", "ex:type2"]
77
- }),
78
- output: %([
79
- {"@type": ["http://example.com/type1", "http://example.com/type2"]}
80
- ])
81
- },
82
- "@value with false": {
83
- input: %({"http://example.com/ex": {"@value": false}}),
84
- output: %([{"http://example.com/ex": [{"@value": false}]}])
85
- },
86
- "compact IRI": {
87
- input: %({
88
- "@context": {"ex": "http://example.com/"},
89
- "ex:p": {"@id": "ex:Sub1"}
90
- }),
91
- output: %([{
92
- "http://example.com/p": [{"@id": "http://example.com/Sub1"}]
93
- }])
94
- },
95
- }.each_pair do |title, params|
96
- it(title) {run_expand params}
97
- end
98
-
99
- context "default language" do
100
- {
101
- "base": {
102
- input: %({
103
- "http://example/foo": "bar"
104
- }),
105
- output: %([{
106
- "http://example/foo": [{"@value": "bar", "@language": "en"}]
107
- }]),
108
- language: "en"
109
- },
110
- "override": {
111
- input: %({
112
- "@context": {"@language": null},
113
- "http://example/foo": "bar"
114
- }),
115
- output: %([{
116
- "http://example/foo": [{"@value": "bar"}]
117
- }]),
118
- language: "en"
119
- }
120
- }.each_pair do |title, params|
121
- it(title) {run_expand params}
122
- end
123
- end
124
-
125
- context "with relative IRIs" do
126
- {
127
- "base": {
128
- input: %({
129
- "@id": "",
130
- "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"
131
- }),
132
- output: %([{
133
- "@id": "http://example.org/",
134
- "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"]
135
- }])
136
- },
137
- "relative": {
138
- input: %({
139
- "@id": "a/b",
140
- "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"
141
- }),
142
- output: %([{
143
- "@id": "http://example.org/a/b",
144
- "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"]
145
- }])
146
- },
147
- "hash": {
148
- input: %({
149
- "@id": "#a",
150
- "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"
151
- }),
152
- output: %([{
153
- "@id": "http://example.org/#a",
154
- "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"]
155
- }])
156
- },
157
- "unmapped @id": {
158
- input: %({
159
- "http://example.com/foo": {"@id": "bar"}
160
- }),
161
- output: %([{
162
- "http://example.com/foo": [{"@id": "http://example.org/bar"}]
163
- }])
164
- },
165
- "json-ld-syntax#66": {
166
- input: %({
167
- "@context": {
168
- "@base": "https://ex.org/",
169
- "u": {"@id": "urn:u:", "@type": "@id"}
170
- },
171
- "u": ["#Test", "#Test:2"]
172
- }),
173
- output: %([{
174
- "urn:u:": [
175
- {"@id": "https://ex.org/#Test"},
176
- {"@id": "https://ex.org/#Test:2"}
177
- ]
178
- }])
179
- }
180
- }.each do |title, params|
181
- it(title) {run_expand params.merge(base: "http://example.org/")}
182
- end
183
- end
184
-
185
- context "with relative property IRIs" do
186
- {
187
- "base": {
188
- input: %({
189
- "http://a/b": "foo"
190
- }),
191
- output: %([{
192
- "http://a/b": [{"@value": "foo"}]
193
- }])
194
- },
195
- "relative": {
196
- input: %({
197
- "a/b": "foo"
198
- }),
199
- output: %([])
200
- },
201
- "hash": {
202
- input: %({
203
- "#a": "foo"
204
- }),
205
- output: %([])
206
- },
207
- "dotseg": {
208
- input: %({
209
- "../a": "foo"
210
- }),
211
- output: %([])
212
- },
213
- }.each do |title, params|
214
- it(title) {run_expand params.merge(base: "http://example.org/")}
215
- end
216
-
217
- context "with @vocab" do
218
- {
219
- "base": {
220
- input: %({
221
- "@context": {"@vocab": "http://vocab/"},
222
- "http://a/b": "foo"
223
- }),
224
- output: %([{
225
- "http://a/b": [{"@value": "foo"}]
226
- }])
227
- },
228
- "relative": {
229
- input: %({
230
- "@context": {"@vocab": "http://vocab/"},
231
- "a/b": "foo"
232
- }),
233
- output: %([{
234
- "http://vocab/a/b": [{"@value": "foo"}]
235
- }])
236
- },
237
- "hash": {
238
- input: %({
239
- "@context": {"@vocab": "http://vocab/"},
240
- "#a": "foo"
241
- }),
242
- output: %([{
243
- "http://vocab/#a": [{"@value": "foo"}]
244
- }])
245
- },
246
- "dotseg": {
247
- input: %({
248
- "@context": {"@vocab": "http://vocab/"},
249
- "../a": "foo"
250
- }),
251
- output: %([{
252
- "http://vocab/../a": [{"@value": "foo"}]
253
- }])
254
- },
255
- }.each do |title, params|
256
- it(title) {run_expand params.merge(base: "http://example.org/")}
257
- end
258
- end
259
-
260
- context "with @vocab: ''" do
261
- {
262
- "base": {
263
- input: %({
264
- "@context": {"@vocab": ""},
265
- "http://a/b": "foo"
266
- }),
267
- output: %([{
268
- "http://a/b": [{"@value": "foo"}]
269
- }])
270
- },
271
- "relative": {
272
- input: %({
273
- "@context": {"@vocab": ""},
274
- "a/b": "foo"
275
- }),
276
- output: %([{
277
- "http://example.org/a/b": [{"@value": "foo"}]
278
- }])
279
- },
280
- "hash": {
281
- input: %({
282
- "@context": {"@vocab": ""},
283
- "#a": "foo"
284
- }),
285
- output: %([{
286
- "http://example.org/#a": [{"@value": "foo"}]
287
- }])
288
- },
289
- "dotseg": {
290
- input: %({
291
- "@context": {"@vocab": ""},
292
- "../a": "foo"
293
- }),
294
- output: %([{
295
- "http://example.org/../a": [{"@value": "foo"}]
296
- }])
297
- },
298
- "example": {
299
- input: %({
300
- "@context": {
301
- "@base": "http://example/document",
302
- "@vocab": ""
303
- },
304
- "@id": "http://example.org/places#BrewEats",
305
- "@type": "#Restaurant",
306
- "#name": "Brew Eats"
307
- }),
308
- output: %([{
309
- "@id": "http://example.org/places#BrewEats",
310
- "@type": ["http://example/document#Restaurant"],
311
- "http://example/document#name": [{"@value": "Brew Eats"}]
312
- }])
313
- }
314
- }.each do |title, params|
315
- it(title) {run_expand params.merge(base: "http://example.org/")}
316
- end
317
- end
318
-
319
- context "with @vocab: '/relative#'" do
320
- {
321
- "base": {
322
- input: %({
323
- "@context": {"@vocab": "/relative#"},
324
- "http://a/b": "foo"
325
- }),
326
- output: %([{
327
- "http://a/b": [{"@value": "foo"}]
328
- }])
329
- },
330
- "relative": {
331
- input: %({
332
- "@context": {"@vocab": "/relative#"},
333
- "a/b": "foo"
334
- }),
335
- output: %([{
336
- "http://example.org/relative#a/b": [{"@value": "foo"}]
337
- }])
338
- },
339
- "hash": {
340
- input: %({
341
- "@context": {"@vocab": "/relative#"},
342
- "#a": "foo"
343
- }),
344
- output: %([{
345
- "http://example.org/relative##a": [{"@value": "foo"}]
346
- }])
347
- },
348
- "dotseg": {
349
- input: %({
350
- "@context": {"@vocab": "/relative#"},
351
- "../a": "foo"
352
- }),
353
- output: %([{
354
- "http://example.org/relative#../a": [{"@value": "foo"}]
355
- }])
356
- },
357
- "example": {
358
- input: %({
359
- "@context": {
360
- "@base": "http://example/document",
361
- "@vocab": "/relative#"
362
- },
363
- "@id": "http://example.org/places#BrewEats",
364
- "@type": "Restaurant",
365
- "name": "Brew Eats"
366
- }),
367
- output: %([{
368
- "@id": "http://example.org/places#BrewEats",
369
- "@type": ["http://example/relative#Restaurant"],
370
- "http://example/relative#name": [{"@value": "Brew Eats"}]
371
- }])
372
- }
373
- }.each do |title, params|
374
- it(title) {run_expand params.merge(base: "http://example.org/")}
375
- end
376
- end
377
- end
378
-
379
- context "keyword aliasing" do
380
- {
381
- "@id": {
382
- input: %({
383
- "@context": {"id": "@id"},
384
- "id": "",
385
- "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"
386
- }),
387
- output: %([{
388
- "@id": "",
389
- "@type":[ "http://www.w3.org/2000/01/rdf-schema#Resource"]
390
- }])
391
- },
392
- "@type": {
393
- input: %({
394
- "@context": {"type": "@type"},
395
- "type": "http://www.w3.org/2000/01/rdf-schema#Resource",
396
- "http://example.com/foo": {"@value": "bar", "type": "http://example.com/baz"}
397
- }),
398
- output: %([{
399
- "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"],
400
- "http://example.com/foo": [{"@value": "bar", "@type": "http://example.com/baz"}]
401
- }])
402
- },
403
- "@language": {
404
- input: %({
405
- "@context": {"language": "@language"},
406
- "http://example.com/foo": {"@value": "bar", "language": "baz"}
407
- }),
408
- output: %([{
409
- "http://example.com/foo": [{"@value": "bar", "@language": "baz"}]
410
- }])
411
- },
412
- "@value": {
413
- input: %({
414
- "@context": {"literal": "@value"},
415
- "http://example.com/foo": {"literal": "bar"}
416
- }),
417
- output: %([{
418
- "http://example.com/foo": [{"@value": "bar"}]
419
- }])
420
- },
421
- "@list": {
422
- input: %({
423
- "@context": {"list": "@list"},
424
- "http://example.com/foo": {"list": ["bar"]}
425
- }),
426
- output: %([{
427
- "http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
428
- }])
429
- },
430
- }.each do |title, params|
431
- it(title) {run_expand params}
432
- end
433
- end
434
-
435
- context "native types" do
436
- {
437
- "true": {
438
- input: %({
439
- "@context": {"e": "http://example.org/vocab#"},
440
- "e:bool": true
441
- }),
442
- output: %([{
443
- "http://example.org/vocab#bool": [{"@value": true}]
444
- }])
445
- },
446
- "false": {
447
- input: %({
448
- "@context": {"e": "http://example.org/vocab#"},
449
- "e:bool": false
450
- }),
451
- output: %([{
452
- "http://example.org/vocab#bool": [{"@value": false}]
453
- }])
454
- },
455
- "double": {
456
- input: %({
457
- "@context": {"e": "http://example.org/vocab#"},
458
- "e:double": 1.23
459
- }),
460
- output: %([{
461
- "http://example.org/vocab#double": [{"@value": 1.23}]
462
- }])
463
- },
464
- "double-zero": {
465
- input: %({
466
- "@context": {"e": "http://example.org/vocab#"},
467
- "e:double-zero": 0.0e0
468
- }),
469
- output: %([{
470
- "http://example.org/vocab#double-zero": [{"@value": 0.0e0}]
471
- }])
472
- },
473
- "integer": {
474
- input: %({
475
- "@context": {"e": "http://example.org/vocab#"},
476
- "e:integer": 123
477
- }),
478
- output: %([{
479
- "http://example.org/vocab#integer": [{"@value": 123}]
480
- }])
481
- },
482
- }.each do |title, params|
483
- it(title) {run_expand params}
484
- end
485
-
486
- context "with @type: @none" do
487
- {
488
- "true": {
489
- input: %({
490
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}},
491
- "e": true
492
- }),
493
- output:%( [{
494
- "http://example.org/vocab#bool": [{"@value": true}]
495
- }])
496
- },
497
- "false": {
498
- input: %({
499
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@none"}},
500
- "e": false
501
- }),
502
- output: %([{
503
- "http://example.org/vocab#bool": [{"@value": false}]
504
- }])
505
- },
506
- "double": {
507
- input: %({
508
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}},
509
- "e": 1.23
510
- }),
511
- output: %([{
512
- "http://example.org/vocab#double": [{"@value": 1.23}]
513
- }])
514
- },
515
- "double-zero": {
516
- input: %({
517
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@none"}},
518
- "e": 0.0e0
519
- }),
520
- output: %([{
521
- "http://example.org/vocab#double": [{"@value": 0.0e0}]
522
- }])
523
- },
524
- "integer": {
525
- input: %({
526
- "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@none"}},
527
- "e": 123
528
- }),
529
- output: %([{
530
- "http://example.org/vocab#integer": [{"@value": 123}]
531
- }])
532
- },
533
- }.each do |title, params|
534
- it(title) {run_expand(processingMode: "json-ld-1.1", **params)}
535
- end
536
- end
537
-
538
- context "with @type: @id" do
539
- {
540
- "true": {
541
- input: %({
542
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@id"}},
543
- "e": true
544
- }),
545
- output:%( [{
546
- "http://example.org/vocab#bool": [{"@value": true}]
547
- }])
548
- },
549
- "false": {
550
- input: %({
551
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@id"}},
552
- "e": false
553
- }),
554
- output: %([{
555
- "http://example.org/vocab#bool": [{"@value": false}]
556
- }])
557
- },
558
- "double": {
559
- input: %({
560
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@id"}},
561
- "e": 1.23
562
- }),
563
- output: %([{
564
- "http://example.org/vocab#double": [{"@value": 1.23}]
565
- }])
566
- },
567
- "double-zero": {
568
- input: %({
569
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@id"}},
570
- "e": 0.0e0
571
- }),
572
- output: %([{
573
- "http://example.org/vocab#double": [{"@value": 0.0e0}]
574
- }])
575
- },
576
- "integer": {
577
- input: %({
578
- "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@id"}},
579
- "e": 123
580
- }),
581
- output: %([{
582
- "http://example.org/vocab#integer": [{"@value": 123}]
583
- }])
584
- },
585
- }.each do |title, params|
586
- it(title) {run_expand params}
587
- end
588
- end
589
-
590
- context "with @type: @vocab" do
591
- {
592
- "true": {
593
- input: %({
594
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@vocab"}},
595
- "e": true
596
- }),
597
- output:%( [{
598
- "http://example.org/vocab#bool": [{"@value": true}]
599
- }])
600
- },
601
- "false": {
602
- input: %({
603
- "@context": {"e": {"@id": "http://example.org/vocab#bool", "@type": "@vocab"}},
604
- "e": false
605
- }),
606
- output: %([{
607
- "http://example.org/vocab#bool": [{"@value": false}]
608
- }])
609
- },
610
- "double": {
611
- input: %({
612
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@vocab"}},
613
- "e": 1.23
614
- }),
615
- output: %([{
616
- "http://example.org/vocab#double": [{"@value": 1.23}]
617
- }])
618
- },
619
- "double-zero": {
620
- input: %({
621
- "@context": {"e": {"@id": "http://example.org/vocab#double", "@type": "@vocab"}},
622
- "e": 0.0e0
623
- }),
624
- output: %([{
625
- "http://example.org/vocab#double": [{"@value": 0.0e0}]
626
- }])
627
- },
628
- "integer": {
629
- input: %({
630
- "@context": {"e": {"@id": "http://example.org/vocab#integer", "@type": "@vocab"}},
631
- "e": 123
632
- }),
633
- output: %([{
634
- "http://example.org/vocab#integer": [{"@value": 123}]
635
- }])
636
- },
637
- }.each do |title, params|
638
- it(title) {run_expand params}
639
- end
640
- end
641
- end
642
-
643
- context "with @type: @json" do
644
- {
645
- "true": {
646
- input: %({
647
- "@context": {
648
- "@version": 1.1,
649
- "e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
650
- },
651
- "e": true
652
- }),
653
- output:%( [{
654
- "http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}]
655
- }])
656
- },
657
- "false": {
658
- input: %({
659
- "@context": {
660
- "@version": 1.1,
661
- "e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
662
- },
663
- "e": false
664
- }),
665
- output: %([{
666
- "http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}]
667
- }])
668
- },
669
- "double": {
670
- input: %({
671
- "@context": {
672
- "@version": 1.1,
673
- "e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
674
- },
675
- "e": 1.23
676
- }),
677
- output: %([{
678
- "http://example.org/vocab#double": [{"@value": 1.23, "@type": "@json"}]
679
- }])
680
- },
681
- "double-zero": {
682
- input: %({
683
- "@context": {
684
- "@version": 1.1,
685
- "e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
686
- },
687
- "e": 0.0e0
688
- }),
689
- output: %([{
690
- "http://example.org/vocab#double": [{"@value": 0.0e0, "@type": "@json"}]
691
- }])
692
- },
693
- "integer": {
694
- input: %({
695
- "@context": {
696
- "@version": 1.1,
697
- "e": {"@id": "http://example.org/vocab#integer", "@type": "@json"}
698
- },
699
- "e": 123
700
- }),
701
- output: %([{
702
- "http://example.org/vocab#integer": [{"@value": 123, "@type": "@json"}]
703
- }])
704
- },
705
- "string": {
706
- input: %({
707
- "@context": {
708
- "@version": 1.1,
709
- "e": {"@id": "http://example.org/vocab#string", "@type": "@json"}
710
- },
711
- "e": "string"
712
- }),
713
- output: %([{
714
- "http://example.org/vocab#string": [{
715
- "@value": "string",
716
- "@type": "@json"
717
- }]
718
- }])
719
- },
720
- "null": {
721
- input: %({
722
- "@context": {
723
- "@version": 1.1,
724
- "e": {"@id": "http://example.org/vocab#null", "@type": "@json"}
725
- },
726
- "e": null
727
- }),
728
- output: %([{
729
- "http://example.org/vocab#null": [{
730
- "@value": null,
731
- "@type": "@json"
732
- }]
733
- }])
734
- },
735
- "object": {
736
- input: %({
737
- "@context": {
738
- "@version": 1.1,
739
- "e": {"@id": "http://example.org/vocab#object", "@type": "@json"}
740
- },
741
- "e": {"foo": "bar"}
742
- }),
743
- output: %([{
744
- "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
745
- }])
746
- },
747
- "array": {
748
- input: %({
749
- "@context": {
750
- "@version": 1.1,
751
- "e": {"@id": "http://example.org/vocab#array", "@type": "@json"}
752
- },
753
- "e": [{"foo": "bar"}]
754
- }),
755
- output: %([{
756
- "http://example.org/vocab#array": [{"@value": [{"foo": "bar"}], "@type": "@json"}]
757
- }])
758
- },
759
- "Does not expand terms inside json": {
760
- input: %({
761
- "@context": {
762
- "@version": 1.1,
763
- "e": {"@id": "http://example.org/vocab#array", "@type": "@json"}
764
- },
765
- "e": [{"e": "bar"}]
766
- }),
767
- output: %([{
768
- "http://example.org/vocab#array": [{"@value": [{"e": "bar"}], "@type": "@json"}]
769
- }])
770
- },
771
- "Already expanded object": {
772
- input: %({
773
- "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
774
- }),
775
- output: %([{
776
- "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
777
- }]),
778
- processingMode: 'json-ld-1.1'
779
- },
780
- "Already expanded object with aliased keys": {
781
- input: %({
782
- "@context": {"@version": 1.1, "value": "@value", "type": "@type", "json": "@json"},
783
- "http://example.org/vocab#object": [{"value": {"foo": "bar"}, "type": "json"}]
784
- }),
785
- output: %([{
786
- "http://example.org/vocab#object": [{"@value": {"foo": "bar"}, "@type": "@json"}]
787
- }])
788
- },
789
- }.each do |title, params|
790
- it(title) {run_expand params}
791
- end
792
- end
793
-
794
- context "coerced typed values" do
795
- {
796
- "boolean": {
797
- input: %({
798
- "@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}},
799
- "foo": "true"
800
- }),
801
- output: %([{
802
- "http://example.org/foo": [{"@value": "true", "@type": "http://www.w3.org/2001/XMLSchema#boolean"}]
803
- }])
804
- },
805
- "date": {
806
- input: %({
807
- "@context": {"foo": {"@id": "http://example.org/foo", "@type": "http://www.w3.org/2001/XMLSchema#date"}},
808
- "foo": "2011-03-26"
809
- }),
810
- output: %([{
811
- "http://example.org/foo": [{"@value": "2011-03-26", "@type": "http://www.w3.org/2001/XMLSchema#date"}]
812
- }])
813
- },
814
- }.each do |title, params|
815
- it(title) {run_expand params}
816
- end
817
- end
818
-
819
- context "null" do
820
- {
821
- "value": {
822
- input: %({"http://example.com/foo": null}),
823
- output: []
824
- },
825
- "@value": {
826
- input: %({"http://example.com/foo": {"@value": null}}),
827
- output: []
828
- },
829
- "@value and non-null @type": {
830
- input: %({"http://example.com/foo": {"@value": null, "@type": "http://type"}}),
831
- output: []
832
- },
833
- "@value and non-null @language": {
834
- input: %({"http://example.com/foo": {"@value": null, "@language": "en"}}),
835
- output: []
836
- },
837
- "array with null elements": {
838
- input: %({"http://example.com/foo": [null]}),
839
- output: %([{"http://example.com/foo": []}])
840
- },
841
- "@set with null @value": {
842
- input: %({
843
- "http://example.com/foo": [
844
- {"@value": null, "@type": "http://example.org/Type"}
845
- ]
846
- }),
847
- output: %([{
848
- "http://example.com/foo": []
849
- }])
850
- }
851
- }.each do |title, params|
852
- it(title) {run_expand params}
853
- end
854
- end
855
-
856
- context "@direction" do
857
- {
858
- "value with coerced null direction": {
859
- input: %({
860
- "@context": {
861
- "@direction": "rtl",
862
- "ex": "http://example.org/vocab#",
863
- "ex:ltr": { "@direction": "ltr" },
864
- "ex:none": { "@direction": null }
865
- },
866
- "ex:rtl": "rtl",
867
- "ex:ltr": "ltr",
868
- "ex:none": "no direction"
869
- }),
870
- output: %([
871
- {
872
- "http://example.org/vocab#rtl": [{"@value": "rtl", "@direction": "rtl"}],
873
- "http://example.org/vocab#ltr": [{"@value": "ltr", "@direction": "ltr"}],
874
- "http://example.org/vocab#none": [{"@value": "no direction"}]
875
- }
876
- ])
877
- }
878
- }.each_pair do |title, params|
879
- it(title) {run_expand params}
880
- end
881
- end
882
-
883
- context "default language" do
884
- {
885
- "value with coerced null language": {
886
- input: %({
887
- "@context": {
888
- "@language": "en",
889
- "ex": "http://example.org/vocab#",
890
- "ex:german": { "@language": "de" },
891
- "ex:nolang": { "@language": null }
892
- },
893
- "ex:german": "german",
894
- "ex:nolang": "no language"
895
- }),
896
- output: %([
897
- {
898
- "http://example.org/vocab#german": [{"@value": "german", "@language": "de"}],
899
- "http://example.org/vocab#nolang": [{"@value": "no language"}]
900
- }
901
- ])
902
- },
903
- }.each do |title, params|
904
- it(title) {run_expand params}
905
- end
906
-
907
- context "and default direction" do
908
- {
909
- "value with coerced null direction": {
910
- input: %({
911
- "@context": {
912
- "@language": "en",
913
- "@direction": "rtl",
914
- "ex": "http://example.org/vocab#",
915
- "ex:ltr": { "@direction": "ltr" },
916
- "ex:none": { "@direction": null },
917
- "ex:german": { "@language": "de" },
918
- "ex:nolang": { "@language": null },
919
- "ex:german_ltr": { "@language": "de", "@direction": "ltr" },
920
- "ex:nolang_ltr": { "@language": null, "@direction": "ltr" },
921
- "ex:none_none": { "@language": null, "@direction": null },
922
- "ex:german_none": { "@language": "de", "@direction": null }
923
- },
924
- "ex:rtl": "rtl en",
925
- "ex:ltr": "ltr en",
926
- "ex:none": "no direction en",
927
- "ex:german": "german rtl",
928
- "ex:nolang": "no language rtl",
929
- "ex:german_ltr": "german ltr",
930
- "ex:nolang_ltr": "no language ltr",
931
- "ex:none_none": "no language or direction",
932
- "ex:german_none": "german no direction"
933
- }),
934
- output: %([
935
- {
936
- "http://example.org/vocab#rtl": [{"@value": "rtl en", "@language": "en", "@direction": "rtl"}],
937
- "http://example.org/vocab#ltr": [{"@value": "ltr en", "@language": "en", "@direction": "ltr"}],
938
- "http://example.org/vocab#none": [{"@value": "no direction en", "@language": "en"}],
939
- "http://example.org/vocab#german": [{"@value": "german rtl", "@language": "de", "@direction": "rtl"}],
940
- "http://example.org/vocab#nolang": [{"@value": "no language rtl", "@direction": "rtl"}],
941
- "http://example.org/vocab#german_ltr": [{"@value": "german ltr", "@language": "de", "@direction": "ltr"}],
942
- "http://example.org/vocab#nolang_ltr": [{"@value": "no language ltr", "@direction": "ltr"}],
943
- "http://example.org/vocab#none_none": [{"@value": "no language or direction"}],
944
- "http://example.org/vocab#german_none": [{"@value": "german no direction", "@language": "de"}]
945
- }
946
- ])
947
- }
948
- }.each_pair do |title, params|
949
- it(title) {run_expand params}
950
- end
951
- end
952
- end
953
-
954
- context "default vocabulary" do
955
- {
956
- "property": {
957
- input: %({
958
- "@context": {"@vocab": "http://example.com/"},
959
- "verb": {"@value": "foo"}
960
- }),
961
- output: %([{
962
- "http://example.com/verb": [{"@value": "foo"}]
963
- }])
964
- },
965
- "datatype": {
966
- input: %({
967
- "@context": {"@vocab": "http://example.com/"},
968
- "http://example.org/verb": {"@value": "foo", "@type": "string"}
969
- }),
970
- output: %([{
971
- "http://example.org/verb": [{"@value": "foo", "@type": "http://example.com/string"}]
972
- }])
973
- },
974
- "expand-0028": {
975
- input: %({
976
- "@context": {
977
- "@vocab": "http://example.org/vocab#",
978
- "date": { "@type": "dateTime" }
979
- },
980
- "@id": "example1",
981
- "@type": "test",
982
- "date": "2011-01-25T00:00:00Z",
983
- "embed": {
984
- "@id": "example2",
985
- "expandedDate": { "@value": "2012-08-01T00:00:00Z", "@type": "dateTime" }
986
- }
987
- }),
988
- output: %([
989
- {
990
- "@id": "http://foo/bar/example1",
991
- "@type": ["http://example.org/vocab#test"],
992
- "http://example.org/vocab#date": [
993
- {
994
- "@value": "2011-01-25T00:00:00Z",
995
- "@type": "http://example.org/vocab#dateTime"
996
- }
997
- ],
998
- "http://example.org/vocab#embed": [
999
- {
1000
- "@id": "http://foo/bar/example2",
1001
- "http://example.org/vocab#expandedDate": [
1002
- {
1003
- "@value": "2012-08-01T00:00:00Z",
1004
- "@type": "http://example.org/vocab#dateTime"
1005
- }
1006
- ]
1007
- }
1008
- ]
1009
- }
1010
- ])
1011
- }
1012
- }.each do |title, params|
1013
- it(title) {run_expand params.merge(base: "http://foo/bar/")}
1014
- end
1015
- end
1016
-
1017
- context "unmapped properties" do
1018
- {
1019
- "unmapped key": {
1020
- input: %({"foo": "bar"}),
1021
- output: []
1022
- },
1023
- "unmapped @type as datatype": {
1024
- input: %({
1025
- "http://example.com/foo": {"@value": "bar", "@type": "baz"}
1026
- }),
1027
- output: %([{
1028
- "http://example.com/foo": [{"@value": "bar", "@type": "http://example/baz"}]
1029
- }])
1030
- },
1031
- "unknown keyword": {
1032
- input: %({"@foo": "bar"}),
1033
- output: []
1034
- },
1035
- "value": {
1036
- input: %({
1037
- "@context": {"ex": {"@id": "http://example.org/idrange", "@type": "@id"}},
1038
- "@id": "http://example.org/Subj",
1039
- "idrange": "unmapped"
1040
- }),
1041
- output: []
1042
- },
1043
- "context reset": {
1044
- input: %({
1045
- "@context": {"ex": "http://example.org/", "prop": "ex:prop"},
1046
- "@id": "http://example.org/id1",
1047
- "prop": "prop",
1048
- "ex:chain": {
1049
- "@context": null,
1050
- "@id": "http://example.org/id2",
1051
- "prop": "prop"
1052
- }
1053
- }),
1054
- output: %([{
1055
- "@id": "http://example.org/id1",
1056
- "http://example.org/prop": [{"@value": "prop"}],
1057
- "http://example.org/chain": [{"@id": "http://example.org/id2"}]
1058
- }])
1059
- }
1060
- }.each do |title, params|
1061
- it(title) {run_expand params.merge(base: "http://example/")}
1062
- end
1063
- end
1064
-
1065
- context "@container: @index" do
1066
- {
1067
- "string annotation": {
1068
- input: %({
1069
- "@context": {
1070
- "container": {
1071
- "@id": "http://example.com/container",
1072
- "@container": "@index"
1073
- }
1074
- },
1075
- "@id": "http://example.com/annotationsTest",
1076
- "container": {
1077
- "en": "The Queen",
1078
- "de": [ "Die Königin", "Ihre Majestät" ]
1079
- }
1080
- }),
1081
- output: %([{
1082
- "@id": "http://example.com/annotationsTest",
1083
- "http://example.com/container": [
1084
- {"@value": "Die Königin", "@index": "de"},
1085
- {"@value": "Ihre Majestät", "@index": "de"},
1086
- {"@value": "The Queen", "@index": "en"}
1087
- ]
1088
- }])
1089
- },
1090
- }.each do |title, params|
1091
- it(title) {run_expand params}
1092
- end
1093
-
1094
- context "@index: property" do
1095
- {
1096
- "error if @version is json-ld-1.0": {
1097
- input: %({
1098
- "@context": {
1099
- "@vocab": "http://example.com/",
1100
- "container": {"@container": "@index", "@index": "prop"}
1101
- },
1102
- "@id": "http://example.com/annotationsTest",
1103
- "container": {
1104
- "en": "The Queen",
1105
- "de": [ "Die Königin", "Ihre Majestät" ]
1106
- }
1107
- }),
1108
- exception: JSON::LD::JsonLdError::InvalidTermDefinition,
1109
- processingMode: 'json-ld-1.0'
1110
- },
1111
- "error if @container does not include @index": {
1112
- input: %({
1113
- "@context": {
1114
- "@version": 1.1,
1115
- "@vocab": "http://example.com/",
1116
- "container": {"@index": "prop"}
1117
- },
1118
- "@id": "http://example.com/annotationsTest",
1119
- "container": {
1120
- "en": "The Queen",
1121
- "de": [ "Die Königin", "Ihre Majestät" ]
1122
- }
1123
- }),
1124
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
1125
- },
1126
- "error if @index is a keyword": {
1127
- input: %({
1128
- "@context": {
1129
- "@version": 1.1,
1130
- "@vocab": "http://example.com/",
1131
- "container": {
1132
- "@id": "http://example.com/container",
1133
- "@container": "@index",
1134
- "@index": "@index"
1135
- }
1136
- },
1137
- "@id": "http://example.com/annotationsTest",
1138
- "container": {
1139
- "en": "The Queen",
1140
- "de": [ "Die Königin", "Ihre Majestät" ]
1141
- }
1142
- }),
1143
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
1144
- },
1145
- "error if @index is not a string": {
1146
- input: %({
1147
- "@context": {
1148
- "@version": 1.1,
1149
- "@vocab": "http://example.com/",
1150
- "container": {
1151
- "@id": "http://example.com/container",
1152
- "@container": "@index",
1153
- "@index": true
1154
- }
1155
- },
1156
- "@id": "http://example.com/annotationsTest",
1157
- "container": {
1158
- "en": "The Queen",
1159
- "de": [ "Die Königin", "Ihre Majestät" ]
1160
- }
1161
- }),
1162
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
1163
- },
1164
- "error if attempting to add property to value object": {
1165
- input: %({
1166
- "@context": {
1167
- "@version": 1.1,
1168
- "@vocab": "http://example.com/",
1169
- "container": {
1170
- "@id": "http://example.com/container",
1171
- "@container": "@index",
1172
- "@index": "prop"
1173
- }
1174
- },
1175
- "@id": "http://example.com/annotationsTest",
1176
- "container": {
1177
- "en": "The Queen",
1178
- "de": [ "Die Königin", "Ihre Majestät" ]
1179
- }
1180
- }),
1181
- exception: JSON::LD::JsonLdError::InvalidValueObject
1182
- },
1183
- "property-valued index expands to property value, instead of @index (value)": {
1184
- input: %({
1185
- "@context": {
1186
- "@version": 1.1,
1187
- "@base": "http://example.com/",
1188
- "@vocab": "http://example.com/",
1189
- "author": {"@type": "@id", "@container": "@index", "@index": "prop"}
1190
- },
1191
- "@id": "article",
1192
- "author": {
1193
- "regular": "person/1",
1194
- "guest": ["person/2", "person/3"]
1195
- }
1196
- }),
1197
- output: %([{
1198
- "@id": "http://example.com/article",
1199
- "http://example.com/author": [
1200
- {"@id": "http://example.com/person/1", "http://example.com/prop": [{"@value": "regular"}]},
1201
- {"@id": "http://example.com/person/2", "http://example.com/prop": [{"@value": "guest"}]},
1202
- {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@value": "guest"}]}
1203
- ]
1204
- }])
1205
- },
1206
- "property-valued index appends to property value, instead of @index (value)": {
1207
- input: %({
1208
- "@context": {
1209
- "@version": 1.1,
1210
- "@base": "http://example.com/",
1211
- "@vocab": "http://example.com/",
1212
- "author": {"@type": "@id", "@container": "@index", "@index": "prop"}
1213
- },
1214
- "@id": "article",
1215
- "author": {
1216
- "regular": {"@id": "person/1", "http://example.com/prop": "foo"},
1217
- "guest": [
1218
- {"@id": "person/2", "prop": "foo"},
1219
- {"@id": "person/3", "prop": "foo"}
1220
- ]
1221
- }
1222
- }),
1223
- output: %([{
1224
- "@id": "http://example.com/article",
1225
- "http://example.com/author": [
1226
- {"@id": "http://example.com/person/1", "http://example.com/prop": [{"@value": "regular"}, {"@value": "foo"}]},
1227
- {"@id": "http://example.com/person/2", "http://example.com/prop": [{"@value": "guest"}, {"@value": "foo"}]},
1228
- {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@value": "guest"}, {"@value": "foo"}]}
1229
- ]
1230
- }])
1231
- },
1232
- "property-valued index expands to property value, instead of @index (node)": {
1233
- input: %({
1234
- "@context": {
1235
- "@version": 1.1,
1236
- "@base": "http://example.com/",
1237
- "@vocab": "http://example.com/",
1238
- "author": {"@type": "@id", "@container": "@index", "@index": "prop"},
1239
- "prop": {"@type": "@vocab"}
1240
- },
1241
- "@id": "http://example.com/article",
1242
- "author": {
1243
- "regular": "person/1",
1244
- "guest": ["person/2", "person/3"]
1245
- }
1246
- }),
1247
- output: %([{
1248
- "@id": "http://example.com/article",
1249
- "http://example.com/author": [
1250
- {"@id": "http://example.com/person/1", "http://example.com/prop": [{"@id": "http://example.com/regular"}]},
1251
- {"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}]},
1252
- {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}]}
1253
- ]
1254
- }])
1255
- },
1256
- "property-valued index appends to property value, instead of @index (node)": {
1257
- input: %({
1258
- "@context": {
1259
- "@version": 1.1,
1260
- "@base": "http://example.com/",
1261
- "@vocab": "http://example.com/",
1262
- "author": {"@type": "@id", "@container": "@index", "@index": "prop"},
1263
- "prop": {"@type": "@vocab"}
1264
- },
1265
- "@id": "http://example.com/article",
1266
- "author": {
1267
- "regular": {"@id": "person/1", "prop": "foo"},
1268
- "guest": [
1269
- {"@id": "person/2", "prop": "foo"},
1270
- {"@id": "person/3", "prop": "foo"}
1271
- ]
1272
- }
1273
- }),
1274
- output: %([{
1275
- "@id": "http://example.com/article",
1276
- "http://example.com/author": [
1277
- {"@id": "http://example.com/person/1", "http://example.com/prop": [{"@id": "http://example.com/regular"}, {"@id": "http://example.com/foo"}]},
1278
- {"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}, {"@id": "http://example.com/foo"}]},
1279
- {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}, {"@id": "http://example.com/foo"}]}
1280
- ]
1281
- }])
1282
- },
1283
- "property-valued index does not output property for @none": {
1284
- input: %({
1285
- "@context": {
1286
- "@version": 1.1,
1287
- "@base": "http://example.com/",
1288
- "@vocab": "http://example.com/",
1289
- "author": {"@type": "@id", "@container": "@index", "@index": "prop"},
1290
- "prop": {"@type": "@vocab"}
1291
- },
1292
- "@id": "http://example.com/article",
1293
- "author": {
1294
- "@none": {"@id": "person/1"},
1295
- "guest": [
1296
- {"@id": "person/2"},
1297
- {"@id": "person/3"}
1298
- ]
1299
- }
1300
- }),
1301
- output: %([{
1302
- "@id": "http://example.com/article",
1303
- "http://example.com/author": [
1304
- {"@id": "http://example.com/person/1"},
1305
- {"@id": "http://example.com/person/2", "http://example.com/prop": [{"@id": "http://example.com/guest"}]},
1306
- {"@id": "http://example.com/person/3", "http://example.com/prop": [{"@id": "http://example.com/guest"}]}
1307
- ]
1308
- }])
1309
- },
1310
- }.each do |title, params|
1311
- it(title) {run_expand(validate: true, **params)}
1312
- end
1313
- end
1314
- end
1315
-
1316
- context "@container: @list" do
1317
- {
1318
- "empty": {
1319
- input: %({"http://example.com/foo": {"@list": []}}),
1320
- output: %([{"http://example.com/foo": [{"@list": []}]}])
1321
- },
1322
- "coerced empty": {
1323
- input: %({
1324
- "@context": {"http://example.com/foo": {"@container": "@list"}},
1325
- "http://example.com/foo": []
1326
- }),
1327
- output: %([{"http://example.com/foo": [{"@list": []}]}])
1328
- },
1329
- "coerced single element": {
1330
- input: %({
1331
- "@context": {"http://example.com/foo": {"@container": "@list"}},
1332
- "http://example.com/foo": [ "foo" ]
1333
- }),
1334
- output: %([{"http://example.com/foo": [{"@list": [{"@value": "foo"}]}]}])
1335
- },
1336
- "coerced multiple elements": {
1337
- input: %({
1338
- "@context": {"http://example.com/foo": {"@container": "@list"}},
1339
- "http://example.com/foo": [ "foo", "bar" ]
1340
- }),
1341
- output: %([{
1342
- "http://example.com/foo": [{"@list": [ {"@value": "foo"}, {"@value": "bar"} ]}]
1343
- }])
1344
- },
1345
- "native values in list": {
1346
- input: %({
1347
- "http://example.com/foo": {"@list": [1, 2]}
1348
- }),
1349
- output: %([{
1350
- "http://example.com/foo": [{"@list": [{"@value": 1}, {"@value": 2}]}]
1351
- }])
1352
- },
1353
- "explicit list with coerced @id values": {
1354
- input: %({
1355
- "@context": {"http://example.com/foo": {"@type": "@id"}},
1356
- "http://example.com/foo": {"@list": ["http://foo", "http://bar"]}
1357
- }),
1358
- output: %([{
1359
- "http://example.com/foo": [{"@list": [{"@id": "http://foo"}, {"@id": "http://bar"}]}]
1360
- }])
1361
- },
1362
- "explicit list with coerced datatype values": {
1363
- input: %({
1364
- "@context": {"http://example.com/foo": {"@type": "http://www.w3.org/2001/XMLSchema#date"}},
1365
- "http://example.com/foo": {"@list": ["2012-04-12"]}
1366
- }),
1367
- output: %([{
1368
- "http://example.com/foo": [{"@list": [{"@value": "2012-04-12", "@type": "http://www.w3.org/2001/XMLSchema#date"}]}]
1369
- }])
1370
- },
1371
- "expand-0004": {
1372
- input: %({
1373
- "@context": {
1374
- "mylist1": {"@id": "http://example.com/mylist1", "@container": "@list"},
1375
- "mylist2": {"@id": "http://example.com/mylist2", "@container": "@list"},
1376
- "myset2": {"@id": "http://example.com/myset2", "@container": "@set"},
1377
- "myset3": {"@id": "http://example.com/myset3", "@container": "@set"}
1378
- },
1379
- "http://example.org/property": { "@list": "one item" }
1380
- }),
1381
- output: %([
1382
- {
1383
- "http://example.org/property": [
1384
- {
1385
- "@list": [
1386
- {
1387
- "@value": "one item"
1388
- }
1389
- ]
1390
- }
1391
- ]
1392
- }
1393
- ])
1394
- },
1395
- "@list containing @list": {
1396
- input: %({
1397
- "http://example.com/foo": {"@list": [{"@list": ["baz"]}]}
1398
- }),
1399
- output: %([{
1400
- "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
1401
- }])
1402
- },
1403
- "@list containing empty @list": {
1404
- input: %({
1405
- "http://example.com/foo": {"@list": [{"@list": []}]}
1406
- }),
1407
- output: %([{
1408
- "http://example.com/foo": [{"@list": [{"@list": []}]}]
1409
- }])
1410
- },
1411
- "@list containing @list (with coercion)": {
1412
- input: %({
1413
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1414
- "foo": [{"@list": ["baz"]}]
1415
- }),
1416
- output: %([{
1417
- "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
1418
- }])
1419
- },
1420
- "@list containing empty @list (with coercion)": {
1421
- input: %({
1422
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1423
- "foo": [{"@list": []}]
1424
- }),
1425
- output: %([{
1426
- "http://example.com/foo": [{"@list": [{"@list": []}]}]
1427
- }])
1428
- },
1429
- "coerced @list containing an array": {
1430
- input: %({
1431
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1432
- "foo": [["baz"]]
1433
- }),
1434
- output: %([{
1435
- "http://example.com/foo": [{"@list": [{"@list": [{"@value": "baz"}]}]}]
1436
- }])
1437
- },
1438
- "coerced @list containing an empty array": {
1439
- input: %({
1440
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1441
- "foo": [[]]
1442
- }),
1443
- output: %([{
1444
- "http://example.com/foo": [{"@list": [{"@list": []}]}]
1445
- }])
1446
- },
1447
- "coerced @list containing deep arrays": {
1448
- input: %({
1449
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1450
- "foo": [[["baz"]]]
1451
- }),
1452
- output: %([{
1453
- "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
1454
- }])
1455
- },
1456
- "coerced @list containing deep empty arrays": {
1457
- input: %({
1458
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1459
- "foo": [[[]]]
1460
- }),
1461
- output: %([{
1462
- "http://example.com/foo": [{"@list": [{"@list": [{"@list": []}]}]}]
1463
- }]),
1464
- },
1465
- "coerced @list containing multiple lists": {
1466
- input: %({
1467
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1468
- "foo": [["a"], ["b"]]
1469
- }),
1470
- output: %([{
1471
- "http://example.com/foo": [{"@list": [
1472
- {"@list": [{"@value": "a"}]},
1473
- {"@list": [{"@value": "b"}]}
1474
- ]}]
1475
- }])
1476
- },
1477
- "coerced @list containing mixed list values": {
1478
- input: %({
1479
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
1480
- "foo": [["a"], "b"]
1481
- }),
1482
- output: %([{
1483
- "http://example.com/foo": [{"@list": [
1484
- {"@list": [{"@value": "a"}]},
1485
- {"@value": "b"}
1486
- ]}]
1487
- }])
1488
- },
1489
- }.each do |title, params|
1490
- it(title) {run_expand params}
1491
- end
1492
- end
1493
-
1494
- context "@container: @set" do
1495
- {
1496
- "empty": {
1497
- input: %({"http://example.com/foo": {"@set": []}}),
1498
- output: %([{"http://example.com/foo": []}])
1499
- },
1500
- "coerced empty": {
1501
- input: %({
1502
- "@context": {"http://example.com/foo": {"@container": "@set"}},
1503
- "http://example.com/foo": []
1504
- }),
1505
- output: %([{
1506
- "http://example.com/foo": []
1507
- }])
1508
- },
1509
- "coerced single element": {
1510
- input: %({
1511
- "@context": {"http://example.com/foo": {"@container": "@set"}},
1512
- "http://example.com/foo": [ "foo" ]
1513
- }),
1514
- output: %([{
1515
- "http://example.com/foo": [ {"@value": "foo"} ]
1516
- }])
1517
- },
1518
- "coerced multiple elements": {
1519
- input: %({
1520
- "@context": {"http://example.com/foo": {"@container": "@set"}},
1521
- "http://example.com/foo": [ "foo", "bar" ]
1522
- }),
1523
- output: %([{
1524
- "http://example.com/foo": [ {"@value": "foo"}, {"@value": "bar"} ]
1525
- }])
1526
- },
1527
- "array containing set": {
1528
- input: %({
1529
- "http://example.com/foo": [{"@set": []}]
1530
- }),
1531
- output: %([{
1532
- "http://example.com/foo": []
1533
- }])
1534
- },
1535
- "Free-floating values in sets": {
1536
- input: %({
1537
- "@context": {"property": "http://example.com/property"},
1538
- "@graph": [{
1539
- "@set": [
1540
- "free-floating strings in set objects are removed",
1541
- {"@id": "http://example.com/free-floating-node"},
1542
- {
1543
- "@id": "http://example.com/node",
1544
- "property": "nodes with properties are not removed"
1545
- }
1546
- ]
1547
- }]
1548
- }),
1549
- output: %([{
1550
- "@id": "http://example.com/node",
1551
- "http://example.com/property": [
1552
- {
1553
- "@value": "nodes with properties are not removed"
1554
- }
1555
- ]
1556
- }])
1557
- }
1558
- }.each do |title, params|
1559
- it(title) {run_expand params}
1560
- end
1561
- end
1562
-
1563
- context "@container: @language" do
1564
- {
1565
- "simple map": {
1566
- input: %({
1567
- "@context": {
1568
- "vocab": "http://example.com/vocab/",
1569
- "label": {
1570
- "@id": "vocab:label",
1571
- "@container": "@language"
1572
- }
1573
- },
1574
- "@id": "http://example.com/queen",
1575
- "label": {
1576
- "en": "The Queen",
1577
- "de": [ "Die Königin", "Ihre Majestät" ]
1578
- }
1579
- }),
1580
- output: %([
1581
- {
1582
- "@id": "http://example.com/queen",
1583
- "http://example.com/vocab/label": [
1584
- {"@value": "Die Königin", "@language": "de"},
1585
- {"@value": "Ihre Majestät", "@language": "de"},
1586
- {"@value": "The Queen", "@language": "en"}
1587
- ]
1588
- }
1589
- ])
1590
- },
1591
- "simple map with @none": {
1592
- input: %({
1593
- "@context": {
1594
- "vocab": "http://example.com/vocab/",
1595
- "label": {
1596
- "@id": "vocab:label",
1597
- "@container": "@language"
1598
- }
1599
- },
1600
- "@id": "http://example.com/queen",
1601
- "label": {
1602
- "en": "The Queen",
1603
- "de": [ "Die Königin", "Ihre Majestät" ],
1604
- "@none": "The Queen"
1605
- }
1606
- }),
1607
- output: %([
1608
- {
1609
- "@id": "http://example.com/queen",
1610
- "http://example.com/vocab/label": [
1611
- {"@value": "The Queen"},
1612
- {"@value": "Die Königin", "@language": "de"},
1613
- {"@value": "Ihre Majestät", "@language": "de"},
1614
- {"@value": "The Queen", "@language": "en"}
1615
- ]
1616
- }
1617
- ])
1618
- },
1619
- "simple map with alias of @none": {
1620
- input: %({
1621
- "@context": {
1622
- "vocab": "http://example.com/vocab/",
1623
- "label": {
1624
- "@id": "vocab:label",
1625
- "@container": "@language"
1626
- },
1627
- "none": "@none"
1628
- },
1629
- "@id": "http://example.com/queen",
1630
- "label": {
1631
- "en": "The Queen",
1632
- "de": [ "Die Königin", "Ihre Majestät" ],
1633
- "none": "The Queen"
1634
- }
1635
- }),
1636
- output: %([
1637
- {
1638
- "@id": "http://example.com/queen",
1639
- "http://example.com/vocab/label": [
1640
- {"@value": "Die Königin", "@language": "de"},
1641
- {"@value": "Ihre Majestät", "@language": "de"},
1642
- {"@value": "The Queen", "@language": "en"},
1643
- {"@value": "The Queen"}
1644
- ]
1645
- }
1646
- ])
1647
- },
1648
- "simple map with default direction": {
1649
- input: %({
1650
- "@context": {
1651
- "@direction": "ltr",
1652
- "vocab": "http://example.com/vocab/",
1653
- "label": {
1654
- "@id": "vocab:label",
1655
- "@container": "@language"
1656
- }
1657
- },
1658
- "@id": "http://example.com/queen",
1659
- "label": {
1660
- "en": "The Queen",
1661
- "de": [ "Die Königin", "Ihre Majestät" ]
1662
- }
1663
- }),
1664
- output: %([
1665
- {
1666
- "@id": "http://example.com/queen",
1667
- "http://example.com/vocab/label": [
1668
- {"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
1669
- {"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
1670
- {"@value": "The Queen", "@language": "en", "@direction": "ltr"}
1671
- ]
1672
- }
1673
- ])
1674
- },
1675
- "simple map with term direction": {
1676
- input: %({
1677
- "@context": {
1678
- "vocab": "http://example.com/vocab/",
1679
- "label": {
1680
- "@id": "vocab:label",
1681
- "@direction": "ltr",
1682
- "@container": "@language"
1683
- }
1684
- },
1685
- "@id": "http://example.com/queen",
1686
- "label": {
1687
- "en": "The Queen",
1688
- "de": [ "Die Königin", "Ihre Majestät" ]
1689
- }
1690
- }),
1691
- output: %([
1692
- {
1693
- "@id": "http://example.com/queen",
1694
- "http://example.com/vocab/label": [
1695
- {"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
1696
- {"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
1697
- {"@value": "The Queen", "@language": "en", "@direction": "ltr"}
1698
- ]
1699
- }
1700
- ])
1701
- },
1702
- "simple map with overriding term direction": {
1703
- input: %({
1704
- "@context": {
1705
- "vocab": "http://example.com/vocab/",
1706
- "@direction": "rtl",
1707
- "label": {
1708
- "@id": "vocab:label",
1709
- "@direction": "ltr",
1710
- "@container": "@language"
1711
- }
1712
- },
1713
- "@id": "http://example.com/queen",
1714
- "label": {
1715
- "en": "The Queen",
1716
- "de": [ "Die Königin", "Ihre Majestät" ]
1717
- }
1718
- }),
1719
- output: %([
1720
- {
1721
- "@id": "http://example.com/queen",
1722
- "http://example.com/vocab/label": [
1723
- {"@value": "Die Königin", "@language": "de", "@direction": "ltr"},
1724
- {"@value": "Ihre Majestät", "@language": "de", "@direction": "ltr"},
1725
- {"@value": "The Queen", "@language": "en", "@direction": "ltr"}
1726
- ]
1727
- }
1728
- ])
1729
- },
1730
- "simple map with overriding null direction": {
1731
- input: %({
1732
- "@context": {
1733
- "vocab": "http://example.com/vocab/",
1734
- "@direction": "rtl",
1735
- "label": {
1736
- "@id": "vocab:label",
1737
- "@direction": null,
1738
- "@container": "@language"
1739
- }
1740
- },
1741
- "@id": "http://example.com/queen",
1742
- "label": {
1743
- "en": "The Queen",
1744
- "de": [ "Die Königin", "Ihre Majestät" ]
1745
- }
1746
- }),
1747
- output: %([
1748
- {
1749
- "@id": "http://example.com/queen",
1750
- "http://example.com/vocab/label": [
1751
- {"@value": "Die Königin", "@language": "de"},
1752
- {"@value": "Ihre Majestät", "@language": "de"},
1753
- {"@value": "The Queen", "@language": "en"}
1754
- ]
1755
- }
1756
- ])
1757
- },
1758
- "expand-0035": {
1759
- input: %({
1760
- "@context": {
1761
- "@vocab": "http://example.com/vocab/",
1762
- "@language": "it",
1763
- "label": {
1764
- "@container": "@language"
1765
- }
1766
- },
1767
- "@id": "http://example.com/queen",
1768
- "label": {
1769
- "en": "The Queen",
1770
- "de": [ "Die Königin", "Ihre Majestät" ]
1771
- },
1772
- "http://example.com/vocab/label": [
1773
- "Il re",
1774
- { "@value": "The king", "@language": "en" }
1775
- ]
1776
- }),
1777
- output: %([
1778
- {
1779
- "@id": "http://example.com/queen",
1780
- "http://example.com/vocab/label": [
1781
- {"@value": "Il re", "@language": "it"},
1782
- {"@value": "The king", "@language": "en"},
1783
- {"@value": "Die Königin", "@language": "de"},
1784
- {"@value": "Ihre Majestät", "@language": "de"},
1785
- {"@value": "The Queen", "@language": "en"}
1786
- ]
1787
- }
1788
- ])
1789
- }
1790
- }.each do |title, params|
1791
- it(title) {run_expand params}
1792
- end
1793
- end
1794
-
1795
- context "@container: @id" do
1796
- {
1797
- "Adds @id to object not having an @id": {
1798
- input: %({
1799
- "@context": {
1800
- "@vocab": "http://example/",
1801
- "idmap": {"@container": "@id"}
1802
- },
1803
- "idmap": {
1804
- "http://example.org/foo": {"label": "Object with @id <foo>"},
1805
- "_:bar": {"label": "Object with @id _:bar"}
1806
- }
1807
- }),
1808
- output: %([{
1809
- "http://example/idmap": [
1810
- {"http://example/label": [{"@value": "Object with @id _:bar"}], "@id": "_:bar"},
1811
- {"http://example/label": [{"@value": "Object with @id <foo>"}], "@id": "http://example.org/foo"}
1812
- ]
1813
- }])
1814
- },
1815
- "Retains @id in object already having an @id": {
1816
- input: %({
1817
- "@context": {
1818
- "@vocab": "http://example/",
1819
- "idmap": {"@container": "@id"}
1820
- },
1821
- "idmap": {
1822
- "http://example.org/foo": {"@id": "http://example.org/bar", "label": "Object with @id <foo>"},
1823
- "_:bar": {"@id": "_:foo", "label": "Object with @id _:bar"}
1824
- }
1825
- }),
1826
- output: %([{
1827
- "http://example/idmap": [
1828
- {"@id": "_:foo", "http://example/label": [{"@value": "Object with @id _:bar"}]},
1829
- {"@id": "http://example.org/bar", "http://example/label": [{"@value": "Object with @id <foo>"}]}
1830
- ]
1831
- }])
1832
- },
1833
- "Adds expanded @id to object": {
1834
- input: %({
1835
- "@context": {
1836
- "@vocab": "http://example/",
1837
- "idmap": {"@container": "@id"}
1838
- },
1839
- "idmap": {
1840
- "foo": {"label": "Object with @id <foo>"}
1841
- }
1842
- }),
1843
- output: %([{
1844
- "http://example/idmap": [
1845
- {"http://example/label": [{"@value": "Object with @id <foo>"}], "@id": "http://example.org/foo"}
1846
- ]
1847
- }]),
1848
- base: "http://example.org/"
1849
- },
1850
- "Raises InvalidContainerMapping if processingMode is 1.0": {
1851
- input: %({
1852
- "@context": {
1853
- "@vocab": "http://example/",
1854
- "idmap": {"@container": "@id"}
1855
- },
1856
- "idmap": {
1857
- "http://example.org/foo": {"label": "Object with @id <foo>"},
1858
- "_:bar": {"label": "Object with @id _:bar"}
1859
- }
1860
- }),
1861
- processingMode: 'json-ld-1.0',
1862
- exception: JSON::LD::JsonLdError::InvalidContainerMapping
1863
- },
1864
- "Does not add @id if it is @none, or expands to @none": {
1865
- input: %({
1866
- "@context": {
1867
- "@vocab": "http://example/",
1868
- "idmap": {"@container": "@id"},
1869
- "none": "@none"
1870
- },
1871
- "idmap": {
1872
- "@none": {"label": "Object with no @id"},
1873
- "none": {"label": "Another object with no @id"}
1874
- }
1875
- }),
1876
- output: %([{
1877
- "http://example/idmap": [
1878
- {"http://example/label": [{"@value": "Object with no @id"}]},
1879
- {"http://example/label": [{"@value": "Another object with no @id"}]}
1880
- ]
1881
- }])
1882
- }
1883
- }.each do |title, params|
1884
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
1885
- end
1886
- end
1887
-
1888
- context "@container: @type" do
1889
- {
1890
- "Adds @type to object not having an @type": {
1891
- input: %({
1892
- "@context": {
1893
- "@vocab": "http://example/",
1894
- "typemap": {"@container": "@type"}
1895
- },
1896
- "typemap": {
1897
- "http://example.org/foo": {"label": "Object with @type <foo>"},
1898
- "_:bar": {"label": "Object with @type _:bar"}
1899
- }
1900
- }),
1901
- output: %([{
1902
- "http://example/typemap": [
1903
- {"http://example/label": [{"@value": "Object with @type _:bar"}], "@type": ["_:bar"]},
1904
- {"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example.org/foo"]}
1905
- ]
1906
- }])
1907
- },
1908
- "Prepends @type in object already having an @type": {
1909
- input: %({
1910
- "@context": {
1911
- "@vocab": "http://example/",
1912
- "typemap": {"@container": "@type"}
1913
- },
1914
- "typemap": {
1915
- "http://example.org/foo": {"@type": "http://example.org/bar", "label": "Object with @type <foo>"},
1916
- "_:bar": {"@type": "_:foo", "label": "Object with @type _:bar"}
1917
- }
1918
- }),
1919
- output: %([{
1920
- "http://example/typemap": [
1921
- {
1922
- "@type": ["_:bar", "_:foo"],
1923
- "http://example/label": [{"@value": "Object with @type _:bar"}]
1924
- },
1925
- {
1926
- "@type": ["http://example.org/foo", "http://example.org/bar"],
1927
- "http://example/label": [{"@value": "Object with @type <foo>"}]
1928
- }
1929
- ]
1930
- }])
1931
- },
1932
- "Adds vocabulary expanded @type to object": {
1933
- input: %({
1934
- "@context": {
1935
- "@vocab": "http://example/",
1936
- "typemap": {"@container": "@type"}
1937
- },
1938
- "typemap": {
1939
- "Foo": {"label": "Object with @type <foo>"}
1940
- }
1941
- }),
1942
- output: %([{
1943
- "http://example/typemap": [
1944
- {"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example/Foo"]}
1945
- ]
1946
- }])
1947
- },
1948
- "Adds document expanded @type to object": {
1949
- input: %({
1950
- "@context": {
1951
- "@vocab": "http://example/",
1952
- "typemap": {"@container": "@type"},
1953
- "label": "http://example/label"
1954
- },
1955
- "typemap": {
1956
- "Foo": {"label": "Object with @type <foo>"}
1957
- }
1958
- }),
1959
- output: %([{
1960
- "http://example/typemap": [
1961
- {"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example/Foo"]}
1962
- ]
1963
- }])
1964
- },
1965
- "Does not add @type if it is @none, or expands to @none": {
1966
- input: %({
1967
- "@context": {
1968
- "@vocab": "http://example/",
1969
- "typemap": {"@container": "@type"},
1970
- "none": "@none"
1971
- },
1972
- "typemap": {
1973
- "@none": {"label": "Object with no @type"},
1974
- "none": {"label": "Another object with no @type"}
1975
- }
1976
- }),
1977
- output: %([{
1978
- "http://example/typemap": [
1979
- {"http://example/label": [{"@value": "Object with no @type"}]},
1980
- {"http://example/label": [{"@value": "Another object with no @type"}]}
1981
- ]
1982
- }])
1983
- },
1984
- "Raises InvalidContainerMapping if processingMode is 1.0": {
1985
- input: %({
1986
- "@context": {
1987
- "@vocab": "http://example/",
1988
- "typemap": {"@container": "@type"}
1989
- },
1990
- "typemap": {
1991
- "http://example.org/foo": {"label": "Object with @type <foo>"},
1992
- "_:bar": {"label": "Object with @type _:bar"}
1993
- }
1994
- }),
1995
- processingMode: 'json-ld-1.0',
1996
- exception: JSON::LD::JsonLdError::InvalidContainerMapping
1997
- },
1998
- }.each do |title, params|
1999
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2000
- end
2001
- end
2002
-
2003
- context "@container: @graph" do
2004
- {
2005
- "Creates a graph object given a value": {
2006
- input: %({
2007
- "@context": {
2008
- "@vocab": "http://example.org/",
2009
- "input": {"@container": "@graph"}
2010
- },
2011
- "input": {
2012
- "value": "x"
2013
- }
2014
- }),
2015
- output: %([{
2016
- "http://example.org/input": [{
2017
- "@graph": [{
2018
- "http://example.org/value": [{"@value": "x"}]
2019
- }]
2020
- }]
2021
- }])
2022
- },
2023
- "Creates a graph object within an array given a value": {
2024
- input: %({
2025
- "@context": {
2026
- "@vocab": "http://example.org/",
2027
- "input": {"@container": ["@graph", "@set"]}
2028
- },
2029
- "input": {
2030
- "value": "x"
2031
- }
2032
- }),
2033
- output: %([{
2034
- "http://example.org/input": [{
2035
- "@graph": [{
2036
- "http://example.org/value": [{"@value": "x"}]
2037
- }]
2038
- }]
2039
- }])
2040
- },
2041
- "Creates an graph object if value is a graph": {
2042
- input: %({
2043
- "@context": {
2044
- "@vocab": "http://example.org/",
2045
- "input": {"@container": "@graph"}
2046
- },
2047
- "input": {
2048
- "@graph": {
2049
- "value": "x"
2050
- }
2051
- }
2052
- }),
2053
- output: %([{
2054
- "http://example.org/input": [{
2055
- "@graph": [{
2056
- "@graph": [{
2057
- "http://example.org/value": [{"@value": "x"}]
2058
- }]
2059
- }]
2060
- }]
2061
- }])
2062
- },
2063
- }.each do |title, params|
2064
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2065
- end
2066
-
2067
- context "+ @index" do
2068
- {
2069
- "Creates a graph object given an indexed value": {
2070
- input: %({
2071
- "@context": {
2072
- "@vocab": "http://example.org/",
2073
- "input": {"@container": ["@graph", "@index"]}
2074
- },
2075
- "input": {
2076
- "g1": {"value": "x"}
2077
- }
2078
- }),
2079
- output: %([{
2080
- "http://example.org/input": [{
2081
- "@index": "g1",
2082
- "@graph": [{
2083
- "http://example.org/value": [{"@value": "x"}]
2084
- }]
2085
- }]
2086
- }])
2087
- },
2088
- "Creates a graph object given an indexed value with index @none": {
2089
- input: %({
2090
- "@context": {
2091
- "@vocab": "http://example.org/",
2092
- "input": {"@container": ["@graph", "@index"]}
2093
- },
2094
- "input": {
2095
- "@none": {"value": "x"}
2096
- }
2097
- }),
2098
- output: %([{
2099
- "http://example.org/input": [{
2100
- "@graph": [{
2101
- "http://example.org/value": [{"@value": "x"}]
2102
- }]
2103
- }]
2104
- }])
2105
- },
2106
- "Creates a graph object given an indexed value with index alias of @none": {
2107
- input: %({
2108
- "@context": {
2109
- "@vocab": "http://example.org/",
2110
- "input": {"@container": ["@graph", "@index"]},
2111
- "none": "@none"
2112
- },
2113
- "input": {
2114
- "none": {"value": "x"}
2115
- }
2116
- }),
2117
- output: %([{
2118
- "http://example.org/input": [{
2119
- "@graph": [{
2120
- "http://example.org/value": [{"@value": "x"}]
2121
- }]
2122
- }]
2123
- }])
2124
- },
2125
- "Creates a graph object given an indexed value with @set": {
2126
- input: %({
2127
- "@context": {
2128
- "@vocab": "http://example.org/",
2129
- "input": {"@container": ["@graph", "@index", "@set"]}
2130
- },
2131
- "input": {
2132
- "g1": {"value": "x"}
2133
- }
2134
- }),
2135
- output: %([{
2136
- "http://example.org/input": [{
2137
- "@index": "g1",
2138
- "@graph": [{
2139
- "http://example.org/value": [{"@value": "x"}]
2140
- }]
2141
- }]
2142
- }])
2143
- },
2144
- "Does not create a new graph object if indexed value is already a graph object": {
2145
- input: %({
2146
- "@context": {
2147
- "@vocab": "http://example.org/",
2148
- "input": {"@container": ["@graph", "@index"]}
2149
- },
2150
- "input": {
2151
- "g1": {
2152
- "@graph": {
2153
- "value": "x"
2154
- }
2155
- }
2156
- }
2157
- }),
2158
- output: %([{
2159
- "http://example.org/input": [{
2160
- "@index": "g1",
2161
- "@graph": [{
2162
- "http://example.org/value": [{"@value": "x"}]
2163
- }]
2164
- }]
2165
- }])
2166
- },
2167
- }.each do |title, params|
2168
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2169
- end
2170
-
2171
- context "@index: property" do
2172
- {
2173
- "it expands to property value, instead of @index": {
2174
- input: %({
2175
- "@context": {
2176
- "@version": 1.1,
2177
- "@vocab": "http://example.org/",
2178
- "input": {"@container": ["@graph", "@index"], "@index": "prop"}
2179
- },
2180
- "input": {
2181
- "g1": {"value": "x"}
2182
- }
2183
- }),
2184
- output: %([{
2185
- "http://example.org/input": [{
2186
- "http://example.org/prop": [{"@value": "g1"}],
2187
- "@graph": [{
2188
- "http://example.org/value": [{"@value": "x"}]
2189
- }]
2190
- }]
2191
- }])
2192
- },
2193
- }.each do |title, params|
2194
- it(title) {run_expand(validate: true, **params)}
2195
- end
2196
- end
2197
- end
2198
-
2199
- context "+ @id" do
2200
- {
2201
- "Creates a graph object given an indexed value": {
2202
- input: %({
2203
- "@context": {
2204
- "@vocab": "http://example.org/",
2205
- "input": {"@container": ["@graph", "@id"]}
2206
- },
2207
- "input": {
2208
- "http://example.com/g1": {"value": "x"}
2209
- }
2210
- }),
2211
- output: %([{
2212
- "http://example.org/input": [{
2213
- "@id": "http://example.com/g1",
2214
- "@graph": [{
2215
- "http://example.org/value": [{"@value": "x"}]
2216
- }]
2217
- }]
2218
- }])
2219
- },
2220
- "Creates a graph object given an indexed value of @none": {
2221
- input: %({
2222
- "@context": {
2223
- "@vocab": "http://example.org/",
2224
- "input": {"@container": ["@graph", "@id"]}
2225
- },
2226
- "input": {
2227
- "@none": {"value": "x"}
2228
- }
2229
- }),
2230
- output: %([{
2231
- "http://example.org/input": [{
2232
- "@graph": [{
2233
- "http://example.org/value": [{"@value": "x"}]
2234
- }]
2235
- }]
2236
- }])
2237
- },
2238
- "Creates a graph object given an indexed value of alias of @none": {
2239
- input: %({
2240
- "@context": {
2241
- "@vocab": "http://example.org/",
2242
- "input": {"@container": ["@graph", "@id"]},
2243
- "none": "@none"
2244
- },
2245
- "input": {
2246
- "none": {"value": "x"}
2247
- }
2248
- }),
2249
- output: %([{
2250
- "http://example.org/input": [{
2251
- "@graph": [{
2252
- "http://example.org/value": [{"@value": "x"}]
2253
- }]
2254
- }]
2255
- }])
2256
- },
2257
- "Creates a graph object given an indexed value with @set": {
2258
- input: %({
2259
- "@context": {
2260
- "@vocab": "http://example.org/",
2261
- "input": {"@container": ["@graph", "@id", "@set"]}
2262
- },
2263
- "input": {
2264
- "http://example.com/g1": {"value": "x"}
2265
- }
2266
- }),
2267
- output: %([{
2268
- "http://example.org/input": [{
2269
- "@id": "http://example.com/g1",
2270
- "@graph": [{
2271
- "http://example.org/value": [{"@value": "x"}]
2272
- }]
2273
- }]
2274
- }])
2275
- },
2276
- "Does not create a new graph object if indexed value is already a graph object": {
2277
- input: %({
2278
- "@context": {
2279
- "@vocab": "http://example.org/",
2280
- "input": {"@container": ["@graph", "@id"]}
2281
- },
2282
- "input": {
2283
- "http://example.com/g1": {
2284
- "@graph": {
2285
- "value": "x"
2286
- }
2287
- }
2288
- }
2289
- }),
2290
- output: %([{
2291
- "http://example.org/input": [{
2292
- "@id": "http://example.com/g1",
2293
- "@graph": [{
2294
- "http://example.org/value": [{"@value": "x"}]
2295
- }]
2296
- }]
2297
- }])
2298
- },
2299
- }.each do |title, params|
2300
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2301
- end
2302
- end
2303
- end
2304
-
2305
- context "@included" do
2306
- {
2307
- "Basic Included array": {
2308
- input: %({
2309
- "@context": {
2310
- "@version": 1.1,
2311
- "@vocab": "http://example.org/"
2312
- },
2313
- "prop": "value",
2314
- "@included": [{
2315
- "prop": "value2"
2316
- }]
2317
- }),
2318
- output: %([{
2319
- "http://example.org/prop": [{"@value": "value"}],
2320
- "@included": [{
2321
- "http://example.org/prop": [{"@value": "value2"}]
2322
- }]
2323
- }])
2324
- },
2325
- "Basic Included object": {
2326
- input: %({
2327
- "@context": {
2328
- "@version": 1.1,
2329
- "@vocab": "http://example.org/"
2330
- },
2331
- "prop": "value",
2332
- "@included": {
2333
- "prop": "value2"
2334
- }
2335
- }),
2336
- output: %([{
2337
- "http://example.org/prop": [{"@value": "value"}],
2338
- "@included": [{
2339
- "http://example.org/prop": [{"@value": "value2"}]
2340
- }]
2341
- }])
2342
- },
2343
- "Multiple properties mapping to @included are folded together": {
2344
- input: %({
2345
- "@context": {
2346
- "@version": 1.1,
2347
- "@vocab": "http://example.org/",
2348
- "included1": "@included",
2349
- "included2": "@included"
2350
- },
2351
- "included1": {"prop": "value1"},
2352
- "included2": {"prop": "value2"}
2353
- }),
2354
- output: %([{
2355
- "@included": [
2356
- {"http://example.org/prop": [{"@value": "value1"}]},
2357
- {"http://example.org/prop": [{"@value": "value2"}]}
2358
- ]
2359
- }])
2360
- },
2361
- "Included containing @included": {
2362
- input: %({
2363
- "@context": {
2364
- "@version": 1.1,
2365
- "@vocab": "http://example.org/"
2366
- },
2367
- "prop": "value",
2368
- "@included": {
2369
- "prop": "value2",
2370
- "@included": {
2371
- "prop": "value3"
2372
- }
2373
- }
2374
- }),
2375
- output: %([{
2376
- "http://example.org/prop": [{"@value": "value"}],
2377
- "@included": [{
2378
- "http://example.org/prop": [{"@value": "value2"}],
2379
- "@included": [{
2380
- "http://example.org/prop": [{"@value": "value3"}]
2381
- }]
2382
- }]
2383
- }])
2384
- },
2385
- "Property value with @included": {
2386
- input: %({
2387
- "@context": {
2388
- "@version": 1.1,
2389
- "@vocab": "http://example.org/"
2390
- },
2391
- "prop": {
2392
- "@type": "Foo",
2393
- "@included": {
2394
- "@type": "Bar"
2395
- }
2396
- }
2397
- }),
2398
- output: %([{
2399
- "http://example.org/prop": [{
2400
- "@type": ["http://example.org/Foo"],
2401
- "@included": [{
2402
- "@type": ["http://example.org/Bar"]
2403
- }]
2404
- }]
2405
- }])
2406
- },
2407
- "json.api example": {
2408
- input: %({
2409
- "@context": {
2410
- "@version": 1.1,
2411
- "@vocab": "http://example.org/vocab#",
2412
- "@base": "http://example.org/base/",
2413
- "id": "@id",
2414
- "type": "@type",
2415
- "data": "@nest",
2416
- "attributes": "@nest",
2417
- "links": "@nest",
2418
- "relationships": "@nest",
2419
- "included": "@included",
2420
- "self": {"@type": "@id"},
2421
- "related": {"@type": "@id"},
2422
- "comments": {
2423
- "@context": {
2424
- "data": null
2425
- }
2426
- }
2427
- },
2428
- "data": [{
2429
- "type": "articles",
2430
- "id": "1",
2431
- "attributes": {
2432
- "title": "JSON:API paints my bikeshed!"
2433
- },
2434
- "links": {
2435
- "self": "http://example.com/articles/1"
2436
- },
2437
- "relationships": {
2438
- "author": {
2439
- "links": {
2440
- "self": "http://example.com/articles/1/relationships/author",
2441
- "related": "http://example.com/articles/1/author"
2442
- },
2443
- "data": { "type": "people", "id": "9" }
2444
- },
2445
- "comments": {
2446
- "links": {
2447
- "self": "http://example.com/articles/1/relationships/comments",
2448
- "related": "http://example.com/articles/1/comments"
2449
- },
2450
- "data": [
2451
- { "type": "comments", "id": "5" },
2452
- { "type": "comments", "id": "12" }
2453
- ]
2454
- }
2455
- }
2456
- }],
2457
- "included": [{
2458
- "type": "people",
2459
- "id": "9",
2460
- "attributes": {
2461
- "first-name": "Dan",
2462
- "last-name": "Gebhardt",
2463
- "twitter": "dgeb"
2464
- },
2465
- "links": {
2466
- "self": "http://example.com/people/9"
2467
- }
2468
- }, {
2469
- "type": "comments",
2470
- "id": "5",
2471
- "attributes": {
2472
- "body": "First!"
2473
- },
2474
- "relationships": {
2475
- "author": {
2476
- "data": { "type": "people", "id": "2" }
2477
- }
2478
- },
2479
- "links": {
2480
- "self": "http://example.com/comments/5"
2481
- }
2482
- }, {
2483
- "type": "comments",
2484
- "id": "12",
2485
- "attributes": {
2486
- "body": "I like XML better"
2487
- },
2488
- "relationships": {
2489
- "author": {
2490
- "data": { "type": "people", "id": "9" }
2491
- }
2492
- },
2493
- "links": {
2494
- "self": "http://example.com/comments/12"
2495
- }
2496
- }]
2497
- }),
2498
- output: %([{
2499
- "@id": "http://example.org/base/1",
2500
- "@type": ["http://example.org/vocab#articles"],
2501
- "http://example.org/vocab#title": [{"@value": "JSON:API paints my bikeshed!"}],
2502
- "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1"}],
2503
- "http://example.org/vocab#author": [{
2504
- "@id": "http://example.org/base/9",
2505
- "@type": ["http://example.org/vocab#people"],
2506
- "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/author"}],
2507
- "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/author"}]
2508
- }],
2509
- "http://example.org/vocab#comments": [{
2510
- "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/comments"}],
2511
- "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/comments"}]
2512
- }],
2513
- "@included": [{
2514
- "@id": "http://example.org/base/9",
2515
- "@type": ["http://example.org/vocab#people"],
2516
- "http://example.org/vocab#first-name": [{"@value": "Dan"}],
2517
- "http://example.org/vocab#last-name": [{"@value": "Gebhardt"}],
2518
- "http://example.org/vocab#twitter": [{"@value": "dgeb"}],
2519
- "http://example.org/vocab#self": [{"@id": "http://example.com/people/9"}]
2520
- }, {
2521
- "@id": "http://example.org/base/5",
2522
- "@type": ["http://example.org/vocab#comments"],
2523
- "http://example.org/vocab#body": [{"@value": "First!"}],
2524
- "http://example.org/vocab#author": [{
2525
- "@id": "http://example.org/base/2",
2526
- "@type": ["http://example.org/vocab#people"]
2527
- }],
2528
- "http://example.org/vocab#self": [{"@id": "http://example.com/comments/5"}]
2529
- }, {
2530
- "@id": "http://example.org/base/12",
2531
- "@type": ["http://example.org/vocab#comments"],
2532
- "http://example.org/vocab#body": [{"@value": "I like XML better"}],
2533
- "http://example.org/vocab#author": [{
2534
- "@id": "http://example.org/base/9",
2535
- "@type": ["http://example.org/vocab#people"]
2536
- }],
2537
- "http://example.org/vocab#self": [{"@id": "http://example.com/comments/12"}]
2538
- }]
2539
- }])
2540
- },
2541
- "Error if @included value is a string": {
2542
- input: %({
2543
- "@context": {
2544
- "@version": 1.1,
2545
- "@vocab": "http://example.org/"
2546
- },
2547
- "@included": "string"
2548
- }),
2549
- exception: JSON::LD::JsonLdError::InvalidIncludedValue
2550
- },
2551
- "Error if @included value is a value object": {
2552
- input: %({
2553
- "@context": {
2554
- "@version": 1.1,
2555
- "@vocab": "http://example.org/"
2556
- },
2557
- "@included": {"@value": "value"}
2558
- }),
2559
- exception: JSON::LD::JsonLdError::InvalidIncludedValue
2560
- },
2561
- "Error if @included value is a list object": {
2562
- input: %({
2563
- "@context": {
2564
- "@version": 1.1,
2565
- "@vocab": "http://example.org/"
2566
- },
2567
- "@included": {"@list": ["value"]}
2568
- }),
2569
- exception: JSON::LD::JsonLdError::InvalidIncludedValue
2570
- },
2571
- }.each do |title, params|
2572
- it(title) {run_expand(params)}
2573
- end
2574
- end
2575
-
2576
- context "@nest" do
2577
- {
2578
- "Expands input using @nest": {
2579
- input: %({
2580
- "@context": {"@vocab": "http://example.org/"},
2581
- "p1": "v1",
2582
- "@nest": {
2583
- "p2": "v2"
2584
- }
2585
- }),
2586
- output: %([{
2587
- "http://example.org/p1": [{"@value": "v1"}],
2588
- "http://example.org/p2": [{"@value": "v2"}]
2589
- }])
2590
- },
2591
- "Expands input using aliased @nest": {
2592
- input: %({
2593
- "@context": {
2594
- "@vocab": "http://example.org/",
2595
- "nest": "@nest"
2596
- },
2597
- "p1": "v1",
2598
- "nest": {
2599
- "p2": "v2"
2600
- }
2601
- }),
2602
- output: %([{
2603
- "http://example.org/p1": [{"@value": "v1"}],
2604
- "http://example.org/p2": [{"@value": "v2"}]
2605
- }])
2606
- },
2607
- "Appends nested values when property at base and nested": {
2608
- input: %({
2609
- "@context": {
2610
- "@vocab": "http://example.org/",
2611
- "nest": "@nest"
2612
- },
2613
- "p1": "v1",
2614
- "nest": {
2615
- "p2": "v3"
2616
- },
2617
- "p2": "v2"
2618
- }),
2619
- output: %([{
2620
- "http://example.org/p1": [{"@value": "v1"}],
2621
- "http://example.org/p2": [
2622
- {"@value": "v2"},
2623
- {"@value": "v3"}
2624
- ]
2625
- }])
2626
- },
2627
- "Appends nested values from all @nest aliases in term order": {
2628
- input: %({
2629
- "@context": {
2630
- "@vocab": "http://example.org/",
2631
- "nest1": "@nest",
2632
- "nest2": "@nest"
2633
- },
2634
- "p1": "v1",
2635
- "nest2": {
2636
- "p2": "v4"
2637
- },
2638
- "p2": "v2",
2639
- "nest1": {
2640
- "p2": "v3"
2641
- }
2642
- }),
2643
- output: %([{
2644
- "http://example.org/p1": [{"@value": "v1"}],
2645
- "http://example.org/p2": [
2646
- {"@value": "v2"},
2647
- {"@value": "v3"},
2648
- {"@value": "v4"}
2649
- ]
2650
- }])
2651
- },
2652
- "Nested nested containers": {
2653
- input: %({
2654
- "@context": {
2655
- "@vocab": "http://example.org/"
2656
- },
2657
- "p1": "v1",
2658
- "@nest": {
2659
- "p2": "v3",
2660
- "@nest": {
2661
- "p2": "v4"
2662
- }
2663
- },
2664
- "p2": "v2"
2665
- }),
2666
- output: %([{
2667
- "http://example.org/p1": [{"@value": "v1"}],
2668
- "http://example.org/p2": [
2669
- {"@value": "v2"},
2670
- {"@value": "v3"},
2671
- {"@value": "v4"}
2672
- ]
2673
- }])
2674
- },
2675
- "Arrays of nested values": {
2676
- input: %({
2677
- "@context": {
2678
- "@vocab": "http://example.org/",
2679
- "nest": "@nest"
2680
- },
2681
- "p1": "v1",
2682
- "nest": {
2683
- "p2": ["v4", "v5"]
2684
- },
2685
- "p2": ["v2", "v3"]
2686
- }),
2687
- output: %([{
2688
- "http://example.org/p1": [{"@value": "v1"}],
2689
- "http://example.org/p2": [
2690
- {"@value": "v2"},
2691
- {"@value": "v3"},
2692
- {"@value": "v4"},
2693
- {"@value": "v5"}
2694
- ]
2695
- }])
2696
- },
2697
- "A nest of arrays": {
2698
- input: %({
2699
- "@context": {
2700
- "@vocab": "http://example.org/",
2701
- "nest": "@nest"
2702
- },
2703
- "p1": "v1",
2704
- "nest": [{
2705
- "p2": "v4"
2706
- }, {
2707
- "p2": "v5"
2708
- }],
2709
- "p2": ["v2", "v3"]
2710
- }),
2711
- output: %([{
2712
- "http://example.org/p1": [{"@value": "v1"}],
2713
- "http://example.org/p2": [
2714
- {"@value": "v2"},
2715
- {"@value": "v3"},
2716
- {"@value": "v4"},
2717
- {"@value": "v5"}
2718
- ]
2719
- }])
2720
- },
2721
- "@nest MUST NOT have a string value": {
2722
- input: %({
2723
- "@context": {"@vocab": "http://example.org/"},
2724
- "@nest": "This should generate an error"
2725
- }),
2726
- exception: JSON::LD::JsonLdError::InvalidNestValue
2727
- },
2728
- "@nest MUST NOT have a boolen value": {
2729
- input: %({
2730
- "@context": {"@vocab": "http://example.org/"},
2731
- "@nest": true
2732
- }),
2733
- exception: JSON::LD::JsonLdError::InvalidNestValue
2734
- },
2735
- "@nest MUST NOT have a numeric value": {
2736
- input: %({
2737
- "@context": {"@vocab": "http://example.org/"},
2738
- "@nest": 1
2739
- }),
2740
- exception: JSON::LD::JsonLdError::InvalidNestValue
2741
- },
2742
- "@nest MUST NOT have a value object value": {
2743
- input: %({
2744
- "@context": {"@vocab": "http://example.org/"},
2745
- "@nest": {"@value": "This should generate an error"}
2746
- }),
2747
- exception: JSON::LD::JsonLdError::InvalidNestValue
2748
- },
2749
- "@nest in term definition MUST NOT be a non-@nest keyword": {
2750
- input: %({
2751
- "@context": {
2752
- "@vocab": "http://example.org/",
2753
- "nest": {"@nest": "@id"}
2754
- },
2755
- "nest": "This should generate an error"
2756
- }),
2757
- exception: JSON::LD::JsonLdError::InvalidNestValue
2758
- },
2759
- "@nest in term definition MUST NOT have a boolen value": {
2760
- input: %({
2761
- "@context": {
2762
- "@vocab": "http://example.org/",
2763
- "nest": {"@nest": true}
2764
- },
2765
- "nest": "This should generate an error"
2766
- }),
2767
- exception: JSON::LD::JsonLdError::InvalidNestValue
2768
- },
2769
- "@nest in term definition MUST NOT have a numeric value": {
2770
- input: %({
2771
- "@context": {
2772
- "@vocab": "http://example.org/",
2773
- "nest": {"@nest": 123}
2774
- },
2775
- "nest": "This should generate an error"
2776
- }),
2777
- exception: JSON::LD::JsonLdError::InvalidNestValue
2778
- },
2779
- "Nested @container: @list": {
2780
- input: %({
2781
- "@context": {
2782
- "@vocab": "http://example.org/",
2783
- "list": {"@container": "@list", "@nest": "nestedlist"},
2784
- "nestedlist": "@nest"
2785
- },
2786
- "nestedlist": {
2787
- "list": ["a", "b"]
2788
- }
2789
- }),
2790
- output: %([{
2791
- "http://example.org/list": [{"@list": [
2792
- {"@value": "a"},
2793
- {"@value": "b"}
2794
- ]}]
2795
- }])
2796
- },
2797
- "Nested @container: @index": {
2798
- input: %({
2799
- "@context": {
2800
- "@vocab": "http://example.org/",
2801
- "index": {"@container": "@index", "@nest": "nestedindex"},
2802
- "nestedindex": "@nest"
2803
- },
2804
- "nestedindex": {
2805
- "index": {
2806
- "A": "a",
2807
- "B": "b"
2808
- }
2809
- }
2810
- }),
2811
- output: %([{
2812
- "http://example.org/index": [
2813
- {"@value": "a", "@index": "A"},
2814
- {"@value": "b", "@index": "B"}
2815
- ]
2816
- }])
2817
- },
2818
- "Nested @container: @language": {
2819
- input: %({
2820
- "@context": {
2821
- "@vocab": "http://example.org/",
2822
- "container": {"@container": "@language", "@nest": "nestedlanguage"},
2823
- "nestedlanguage": "@nest"
2824
- },
2825
- "nestedlanguage": {
2826
- "container": {
2827
- "en": "The Queen",
2828
- "de": "Die Königin"
2829
- }
2830
- }
2831
- }),
2832
- output: %([{
2833
- "http://example.org/container": [
2834
- {"@value": "Die Königin", "@language": "de"},
2835
- {"@value": "The Queen", "@language": "en"}
2836
- ]
2837
- }])
2838
- },
2839
- "Nested @container: @type": {
2840
- input: %({
2841
- "@context": {
2842
- "@vocab": "http://example/",
2843
- "typemap": {"@container": "@type", "@nest": "nestedtypemap"},
2844
- "nestedtypemap": "@nest"
2845
- },
2846
- "nestedtypemap": {
2847
- "typemap": {
2848
- "http://example.org/foo": {"label": "Object with @type <foo>"},
2849
- "_:bar": {"label": "Object with @type _:bar"}
2850
- }
2851
- }
2852
- }),
2853
- output: %([{
2854
- "http://example/typemap": [
2855
- {"http://example/label": [{"@value": "Object with @type _:bar"}], "@type": ["_:bar"]},
2856
- {"http://example/label": [{"@value": "Object with @type <foo>"}], "@type": ["http://example.org/foo"]}
2857
- ]
2858
- }])
2859
- },
2860
- "Nested @container: @id": {
2861
- input: %({
2862
- "@context": {
2863
- "@vocab": "http://example/",
2864
- "idmap": {"@container": "@id", "@nest": "nestedidmap"},
2865
- "nestedidmap": "@nest"
2866
- },
2867
- "nestedidmap": {
2868
- "idmap": {
2869
- "http://example.org/foo": {"label": "Object with @id <foo>"},
2870
- "_:bar": {"label": "Object with @id _:bar"}
2871
- }
2872
- }
2873
- }),
2874
- output: %([{
2875
- "http://example/idmap": [
2876
- {"http://example/label": [{"@value": "Object with @id _:bar"}], "@id": "_:bar"},
2877
- {"http://example/label": [{"@value": "Object with @id <foo>"}], "@id": "http://example.org/foo"}
2878
- ]
2879
- }])
2880
- },
2881
- "Nest term an invalid keyword": {
2882
- input: %({
2883
- "@context": {
2884
- "term": {"@id": "http://example/term", "@nest": "@id"}
2885
- }
2886
- }),
2887
- exception: JSON::LD::JsonLdError::InvalidNestValue
2888
- },
2889
- "Nest in @reverse": {
2890
- input: %({
2891
- "@context": {
2892
- "term": {"@reverse": "http://example/term", "@nest": "@nest"}
2893
- }
2894
- }),
2895
- exception: JSON::LD::JsonLdError::InvalidReverseProperty
2896
- },
2897
- "Raises InvalidTermDefinition if processingMode is 1.0": {
2898
- input: %({
2899
- "@context": {
2900
- "@vocab": "http://example.org/",
2901
- "list": {"@container": "@list", "@nest": "nestedlist"},
2902
- "nestedlist": "@nest"
2903
- },
2904
- "nestedlist": {
2905
- "list": ["a", "b"]
2906
- }
2907
- }),
2908
- processingMode: 'json-ld-1.0',
2909
- validate: true,
2910
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
2911
- },
2912
- "Applies property scoped contexts which are aliases of @nest": {
2913
- input: %({
2914
- "@context": {
2915
- "@version": 1.1,
2916
- "@vocab": "http://example.org/",
2917
- "nest": {
2918
- "@id": "@nest",
2919
- "@context": {
2920
- "@vocab": "http://example.org/nest/"
2921
- }
2922
- }
2923
- },
2924
- "nest": {
2925
- "property": "should be in /nest"
2926
- }
2927
- }),
2928
- output: %([{
2929
- "http://example.org/nest/property": [{"@value": "should be in /nest"}]
2930
- }])
2931
- }
2932
- }.each do |title, params|
2933
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
2934
- end
2935
- end
2936
-
2937
- context "scoped context" do
2938
- {
2939
- "adding new term": {
2940
- input: %({
2941
- "@context": {
2942
- "@vocab": "http://example/",
2943
- "foo": {"@context": {"bar": "http://example.org/bar"}}
2944
- },
2945
- "foo": {
2946
- "bar": "baz"
2947
- }
2948
- }),
2949
- output: %([
2950
- {
2951
- "http://example/foo": [{"http://example.org/bar": [{"@value": "baz"}]}]
2952
- }
2953
- ])
2954
- },
2955
- "overriding a term": {
2956
- input: %({
2957
- "@context": {
2958
- "@vocab": "http://example/",
2959
- "foo": {"@context": {"bar": {"@type": "@id"}}},
2960
- "bar": {"@type": "http://www.w3.org/2001/XMLSchema#string"}
2961
- },
2962
- "foo": {
2963
- "bar": "http://example/baz"
2964
- }
2965
- }),
2966
- output: %([
2967
- {
2968
- "http://example/foo": [{"http://example/bar": [{"@id": "http://example/baz"}]}]
2969
- }
2970
- ])
2971
- },
2972
- "property and value with different terms mapping to the same expanded property": {
2973
- input: %({
2974
- "@context": {
2975
- "@vocab": "http://example/",
2976
- "foo": {"@context": {"Bar": {"@id": "bar"}}}
2977
- },
2978
- "foo": {
2979
- "Bar": "baz"
2980
- }
2981
- }),
2982
- output: %([
2983
- {
2984
- "http://example/foo": [{
2985
- "http://example/bar": [
2986
- {"@value": "baz"}
2987
- ]}
2988
- ]
2989
- }
2990
- ])
2991
- },
2992
- "deep @context affects nested nodes": {
2993
- input: %({
2994
- "@context": {
2995
- "@vocab": "http://example/",
2996
- "foo": {"@context": {"baz": {"@type": "@vocab"}}}
2997
- },
2998
- "foo": {
2999
- "bar": {
3000
- "baz": "buzz"
3001
- }
3002
- }
3003
- }),
3004
- output: %([
3005
- {
3006
- "http://example/foo": [{
3007
- "http://example/bar": [{
3008
- "http://example/baz": [{"@id": "http://example/buzz"}]
3009
- }]
3010
- }]
3011
- }
3012
- ])
3013
- },
3014
- "scoped context layers on intemediate contexts": {
3015
- input: %({
3016
- "@context": {
3017
- "@vocab": "http://example/",
3018
- "b": {"@context": {"c": "http://example.org/c"}}
3019
- },
3020
- "a": {
3021
- "@context": {"@vocab": "http://example.com/"},
3022
- "b": {
3023
- "a": "A in example.com",
3024
- "c": "C in example.org"
3025
- },
3026
- "c": "C in example.com"
3027
- },
3028
- "c": "C in example"
3029
- }),
3030
- output: %([{
3031
- "http://example/a": [{
3032
- "http://example.com/c": [{"@value": "C in example.com"}],
3033
- "http://example/b": [{
3034
- "http://example.com/a": [{"@value": "A in example.com"}],
3035
- "http://example.org/c": [{"@value": "C in example.org"}]
3036
- }]
3037
- }],
3038
- "http://example/c": [{"@value": "C in example"}]
3039
- }])
3040
- },
3041
- "Raises InvalidTermDefinition if processingMode is 1.0": {
3042
- input: %({
3043
- "@context": {
3044
- "@vocab": "http://example/",
3045
- "foo": {"@context": {"bar": "http://example.org/bar"}}
3046
- },
3047
- "foo": {
3048
- "bar": "baz"
3049
- }
3050
- }),
3051
- processingMode: 'json-ld-1.0',
3052
- validate: true,
3053
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
3054
- },
3055
- "Scoped on id map": {
3056
- input: %({
3057
- "@context": {
3058
- "@version": 1.1,
3059
- "schema": "http://schema.org/",
3060
- "name": "schema:name",
3061
- "body": "schema:articleBody",
3062
- "words": "schema:wordCount",
3063
- "post": {
3064
- "@id": "schema:blogPost",
3065
- "@container": "@id",
3066
- "@context": {
3067
- "@base": "http://example.com/posts/"
3068
- }
3069
- }
3070
- },
3071
- "@id": "http://example.com/",
3072
- "@type": "schema:Blog",
3073
- "name": "World Financial News",
3074
- "post": {
3075
- "1/en": {
3076
- "body": "World commodities were up today with heavy trading of crude oil...",
3077
- "words": 1539
3078
- },
3079
- "1/de": {
3080
- "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...",
3081
- "words": 1204
3082
- }
3083
- }
3084
- }),
3085
- output: %([{
3086
- "@id": "http://example.com/",
3087
- "@type": ["http://schema.org/Blog"],
3088
- "http://schema.org/name": [{"@value": "World Financial News"}],
3089
- "http://schema.org/blogPost": [{
3090
- "@id": "http://example.com/posts/1/en",
3091
- "http://schema.org/articleBody": [
3092
- {"@value": "World commodities were up today with heavy trading of crude oil..."}
3093
- ],
3094
- "http://schema.org/wordCount": [{"@value": 1539}]
3095
- }, {
3096
- "@id": "http://example.com/posts/1/de",
3097
- "http://schema.org/articleBody": [
3098
- {"@value": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl..."}
3099
- ],
3100
- "http://schema.org/wordCount": [{"@value": 1204}]
3101
- }]
3102
- }])
3103
- }
3104
- }.each do |title, params|
3105
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
3106
- end
3107
- end
3108
-
3109
- context "scoped context on @type" do
3110
- {
3111
- "adding new term": {
3112
- input: %({
3113
- "@context": {
3114
- "@vocab": "http://example/",
3115
- "Foo": {"@context": {"bar": "http://example.org/bar"}}
3116
- },
3117
- "a": {"@type": "Foo", "bar": "baz"}
3118
- }),
3119
- output: %([
3120
- {
3121
- "http://example/a": [{
3122
- "@type": ["http://example/Foo"],
3123
- "http://example.org/bar": [{"@value": "baz"}]
3124
- }]
3125
- }
3126
- ])
3127
- },
3128
- "overriding a term": {
3129
- input: %({
3130
- "@context": {
3131
- "@vocab": "http://example/",
3132
- "Foo": {"@context": {"bar": {"@type": "@id"}}},
3133
- "bar": {"@type": "http://www.w3.org/2001/XMLSchema#string"}
3134
- },
3135
- "a": {"@type": "Foo", "bar": "http://example/baz"}
3136
- }),
3137
- output: %([
3138
- {
3139
- "http://example/a": [{
3140
- "@type": ["http://example/Foo"],
3141
- "http://example/bar": [{"@id": "http://example/baz"}]
3142
- }]
3143
- }
3144
- ])
3145
- },
3146
- "alias of @type": {
3147
- input: %({
3148
- "@context": {
3149
- "@vocab": "http://example/",
3150
- "type": "@type",
3151
- "Foo": {"@context": {"bar": "http://example.org/bar"}}
3152
- },
3153
- "a": {"type": "Foo", "bar": "baz"}
3154
- }),
3155
- output: %([
3156
- {
3157
- "http://example/a": [{
3158
- "@type": ["http://example/Foo"],
3159
- "http://example.org/bar": [{"@value": "baz"}]
3160
- }]
3161
- }
3162
- ])
3163
- },
3164
- "deep @context does not affect nested nodes": {
3165
- input: %({
3166
- "@context": {
3167
- "@vocab": "http://example/",
3168
- "Foo": {"@context": {"baz": {"@type": "@vocab"}}}
3169
- },
3170
- "@type": "Foo",
3171
- "bar": {"baz": "buzz"}
3172
- }),
3173
- output: %([
3174
- {
3175
- "@type": ["http://example/Foo"],
3176
- "http://example/bar": [{
3177
- "http://example/baz": [{"@value": "buzz"}]
3178
- }]
3179
- }
3180
- ])
3181
- },
3182
- "scoped context layers on intemediate contexts": {
3183
- input: %({
3184
- "@context": {
3185
- "@vocab": "http://example/",
3186
- "B": {"@context": {"c": "http://example.org/c"}}
3187
- },
3188
- "a": {
3189
- "@context": {"@vocab": "http://example.com/"},
3190
- "@type": "B",
3191
- "a": "A in example.com",
3192
- "c": "C in example.org"
3193
- },
3194
- "c": "C in example"
3195
- }),
3196
- output: %([{
3197
- "http://example/a": [{
3198
- "@type": ["http://example/B"],
3199
- "http://example.com/a": [{"@value": "A in example.com"}],
3200
- "http://example.org/c": [{"@value": "C in example.org"}]
3201
- }],
3202
- "http://example/c": [{"@value": "C in example"}]
3203
- }])
3204
- },
3205
- "with @container: @type": {
3206
- input: %({
3207
- "@context": {
3208
- "@vocab": "http://example/",
3209
- "typemap": {"@container": "@type"},
3210
- "Type": {"@context": {"a": "http://example.org/a"}}
3211
- },
3212
- "typemap": {
3213
- "Type": {"a": "Object with @type <Type>"}
3214
- }
3215
- }),
3216
- output: %([{
3217
- "http://example/typemap": [
3218
- {"http://example.org/a": [{"@value": "Object with @type <Type>"}], "@type": ["http://example/Type"]}
3219
- ]
3220
- }])
3221
- },
3222
- "orders lexicographically": {
3223
- input: %({
3224
- "@context": {
3225
- "@vocab": "http://example/",
3226
- "t1": {"@context": {"foo": {"@id": "http://example.com/foo"}}},
3227
- "t2": {"@context": {"foo": {"@id": "http://example.org/foo", "@type": "@id"}}}
3228
- },
3229
- "@type": ["t2", "t1"],
3230
- "foo": "urn:bar"
3231
- }),
3232
- output: %([{
3233
- "@type": ["http://example/t2", "http://example/t1"],
3234
- "http://example.org/foo": [
3235
- {"@id": "urn:bar"}
3236
- ]
3237
- }])
3238
- },
3239
- "Raises InvalidTermDefinition if processingMode is 1.0": {
3240
- input: %({
3241
- "@context": {
3242
- "@vocab": "http://example/",
3243
- "Foo": {"@context": {"bar": "http://example.org/bar"}}
3244
- },
3245
- "a": {"@type": "Foo", "bar": "baz"}
3246
- }),
3247
- processingMode: 'json-ld-1.0',
3248
- validate: true,
3249
- exception: JSON::LD::JsonLdError::InvalidTermDefinition
3250
- },
3251
- }.each do |title, params|
3252
- it(title) {run_expand({processingMode: "json-ld-1.1"}.merge(params))}
3253
- end
3254
- end
3255
-
3256
- context "@reverse" do
3257
- {
3258
- "@container: @reverse": {
3259
- input: %({
3260
- "@context": {
3261
- "@vocab": "http://example/",
3262
- "rev": { "@reverse": "forward", "@type": "@id"}
3263
- },
3264
- "@id": "http://example/one",
3265
- "rev": "http://example/two"
3266
- }),
3267
- output: %([{
3268
- "@id": "http://example/one",
3269
- "@reverse": {
3270
- "http://example/forward": [
3271
- {
3272
- "@id": "http://example/two"
3273
- }
3274
- ]
3275
- }
3276
- }])
3277
- },
3278
- "expand-0037": {
3279
- input: %({
3280
- "@context": {
3281
- "name": "http://xmlns.com/foaf/0.1/name"
3282
- },
3283
- "@id": "http://example.com/people/markus",
3284
- "name": "Markus Lanthaler",
3285
- "@reverse": {
3286
- "http://xmlns.com/foaf/0.1/knows": {
3287
- "@id": "http://example.com/people/dave",
3288
- "name": "Dave Longley"
3289
- }
3290
- }
3291
- }),
3292
- output: %([
3293
- {
3294
- "@id": "http://example.com/people/markus",
3295
- "@reverse": {
3296
- "http://xmlns.com/foaf/0.1/knows": [
3297
- {
3298
- "@id": "http://example.com/people/dave",
3299
- "http://xmlns.com/foaf/0.1/name": [
3300
- {
3301
- "@value": "Dave Longley"
3302
- }
3303
- ]
3304
- }
3305
- ]
3306
- },
3307
- "http://xmlns.com/foaf/0.1/name": [
3308
- {
3309
- "@value": "Markus Lanthaler"
3310
- }
3311
- ]
3312
- }
3313
- ])
3314
- },
3315
- "expand-0043": {
3316
- input: %({
3317
- "@context": {
3318
- "name": "http://xmlns.com/foaf/0.1/name",
3319
- "isKnownBy": { "@reverse": "http://xmlns.com/foaf/0.1/knows" }
3320
- },
3321
- "@id": "http://example.com/people/markus",
3322
- "name": "Markus Lanthaler",
3323
- "@reverse": {
3324
- "isKnownBy": [
3325
- {
3326
- "@id": "http://example.com/people/dave",
3327
- "name": "Dave Longley"
3328
- },
3329
- {
3330
- "@id": "http://example.com/people/gregg",
3331
- "name": "Gregg Kellogg"
3332
- }
3333
- ]
3334
- }
3335
- }),
3336
- output: %([
3337
- {
3338
- "@id": "http://example.com/people/markus",
3339
- "http://xmlns.com/foaf/0.1/knows": [
3340
- {
3341
- "@id": "http://example.com/people/dave",
3342
- "http://xmlns.com/foaf/0.1/name": [
3343
- {
3344
- "@value": "Dave Longley"
3345
- }
3346
- ]
3347
- },
3348
- {
3349
- "@id": "http://example.com/people/gregg",
3350
- "http://xmlns.com/foaf/0.1/name": [
3351
- {
3352
- "@value": "Gregg Kellogg"
3353
- }
3354
- ]
3355
- }
3356
- ],
3357
- "http://xmlns.com/foaf/0.1/name": [
3358
- {
3359
- "@value": "Markus Lanthaler"
3360
- }
3361
- ]
3362
- }
3363
- ])
3364
- },
3365
- "@reverse object with an @id property": {
3366
- input: %({
3367
- "@id": "http://example/foo",
3368
- "@reverse": {
3369
- "@id": "http://example/bar"
3370
- }
3371
- }),
3372
- exception: JSON::LD::JsonLdError::InvalidReversePropertyMap,
3373
- },
3374
- "Explicit and implicit @reverse in same object": {
3375
- input: %({
3376
- "@context": {
3377
- "fooOf": {"@reverse": "ex:foo", "@type": "@id"}
3378
- },
3379
- "@id": "ex:s",
3380
- "fooOf": "ex:o1",
3381
- "@reverse": {
3382
- "ex:bar": {"@id": "ex:o2"}
3383
- }
3384
- }),
3385
- output: %([{
3386
- "@id": "ex:s",
3387
- "@reverse": {
3388
- "ex:bar": [{"@id": "ex:o2"}],
3389
- "ex:foo": [{"@id": "ex:o1"}]
3390
- }
3391
- }])
3392
- },
3393
- "Two properties both with @reverse": {
3394
- input: %({
3395
- "@context": {
3396
- "fooOf": {"@reverse": "ex:foo", "@type": "@id"},
3397
- "barOf": {"@reverse": "ex:bar", "@type": "@id"}
3398
- },
3399
- "@id": "ex:s",
3400
- "fooOf": "ex:o1",
3401
- "barOf": "ex:o2"
3402
- }),
3403
- output: %([{
3404
- "@id": "ex:s",
3405
- "@reverse": {
3406
- "ex:bar": [{"@id": "ex:o2"}],
3407
- "ex:foo": [{"@id": "ex:o1"}]
3408
- }
3409
- }])
3410
- },
3411
- }.each do |title, params|
3412
- it(title) {run_expand params}
3413
- end
3414
- end
3415
-
3416
- context "JSON-LD-star" do
3417
- {
3418
- "node with embedded subject without rdfstar option": {
3419
- input: %({
3420
- "@id": {
3421
- "@id": "ex:rei",
3422
- "ex:prop": "value"
3423
- },
3424
- "ex:prop": "value2"
3425
- }),
3426
- exception: JSON::LD::JsonLdError::InvalidIdValue
3427
- },
3428
- "node object with @annotation property is ignored without rdfstar option": {
3429
- input: %({
3430
- "@id": "ex:bob",
3431
- "ex:knows": {
3432
- "@id": "ex:fred",
3433
- "@annotation": {
3434
- "ex:certainty": 0.8
3435
- }
3436
- }
3437
- }),
3438
- output: %([{
3439
- "@id": "ex:bob",
3440
- "ex:knows": [{"@id": "ex:fred"}]
3441
- }])
3442
- },
3443
- "value object with @annotation property is ignored without rdfstar option": {
3444
- input: %({
3445
- "@id": "ex:bob",
3446
- "ex:age": {
3447
- "@value": 23,
3448
- "@annotation": {
3449
- "ex:certainty": 0.8
3450
- }
3451
- }
3452
- }),
3453
- output: %([{
3454
- "@id": "ex:bob",
3455
- "ex:age": [{"@value": 23}]
3456
- }])
3457
- },
3458
- }.each do |title, params|
3459
- it(title) {run_expand params}
3460
- end
3461
-
3462
- {
3463
- "node with embedded subject having no @id": {
3464
- input: %({
3465
- "@id": {
3466
- "ex:prop": "value"
3467
- },
3468
- "ex:prop": "value2"
3469
- }),
3470
- output: %([{
3471
- "@id": {
3472
- "ex:prop": [{"@value": "value"}]
3473
- },
3474
- "ex:prop": [{"@value": "value2"}]
3475
- }])
3476
- },
3477
- "node with embedded subject having IRI @id": {
3478
- input: %({
3479
- "@id": {
3480
- "@id": "ex:rei",
3481
- "ex:prop": "value"
3482
- },
3483
- "ex:prop": "value2"
3484
- }),
3485
- output: %([{
3486
- "@id": {
3487
- "@id": "ex:rei",
3488
- "ex:prop": [{"@value": "value"}]
3489
- },
3490
- "ex:prop": [{"@value": "value2"}]
3491
- }])
3492
- },
3493
- "node with embedded subject having BNode @id": {
3494
- input: %({
3495
- "@id": {
3496
- "@id": "_:rei",
3497
- "ex:prop": "value"
3498
- },
3499
- "ex:prop": "value2"
3500
- }),
3501
- output: %([{
3502
- "@id": {
3503
- "@id": "_:rei",
3504
- "ex:prop": [{"@value": "value"}]
3505
- },
3506
- "ex:prop": [{"@value": "value2"}]
3507
- }])
3508
- },
3509
- "node with embedded subject having a type": {
3510
- input: %({
3511
- "@id": {
3512
- "@id": "ex:rei",
3513
- "@type": "ex:Type"
3514
- },
3515
- "ex:prop": "value2"
3516
- }),
3517
- output: %([{
3518
- "@id": {
3519
- "@id": "ex:rei",
3520
- "@type": ["ex:Type"]
3521
- },
3522
- "ex:prop": [{"@value": "value2"}]
3523
- }])
3524
- },
3525
- "node with embedded subject having an IRI value": {
3526
- input: %({
3527
- "@id": {
3528
- "@id": "ex:rei",
3529
- "ex:prop": {"@id": "ex:value"}
3530
- },
3531
- "ex:prop": "value2"
3532
- }),
3533
- output: %([{
3534
- "@id": {
3535
- "@id": "ex:rei",
3536
- "ex:prop": [{"@id": "ex:value"}]
3537
- },
3538
- "ex:prop": [{"@value": "value2"}]
3539
- }])
3540
- },
3541
- "node with embedded subject having an BNode value": {
3542
- input: %({
3543
- "@id": {
3544
- "@id": "ex:rei",
3545
- "ex:prop": {"@id": "_:value"}
3546
- },
3547
- "ex:prop": "value2"
3548
- }),
3549
- output: %([{
3550
- "@id": {
3551
- "@id": "ex:rei",
3552
- "ex:prop": [{"@id": "_:value"}]
3553
- },
3554
- "ex:prop": [{"@value": "value2"}]
3555
- }])
3556
- },
3557
- "node with recursive embedded subject": {
3558
- input: %({
3559
- "@id": {
3560
- "@id": {
3561
- "@id": "ex:rei",
3562
- "ex:prop": "value3"
3563
- },
3564
- "ex:prop": "value"
3565
- },
3566
- "ex:prop": "value2"
3567
- }),
3568
- output: %([{
3569
- "@id": {
3570
- "@id": {
3571
- "@id": "ex:rei",
3572
- "ex:prop": [{"@value": "value3"}]
3573
- },
3574
- "ex:prop": [{"@value": "value"}]
3575
- },
3576
- "ex:prop": [{"@value": "value2"}]
3577
- }])
3578
- },
3579
- "illegal node with subject having no property": {
3580
- input: %({
3581
- "@id": {
3582
- "@id": "ex:rei"
3583
- },
3584
- "ex:prop": "value3"
3585
- }),
3586
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3587
- },
3588
- "illegal node with subject having multiple properties": {
3589
- input: %({
3590
- "@id": {
3591
- "@id": "ex:rei",
3592
- "ex:prop": ["value1", "value2"]
3593
- },
3594
- "ex:prop": "value3"
3595
- }),
3596
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3597
- },
3598
- "illegal node with subject having multiple types": {
3599
- input: %({
3600
- "@id": {
3601
- "@id": "ex:rei",
3602
- "@type": ["ex:Type1", "ex:Type2"]
3603
- },
3604
- "ex:prop": "value3"
3605
- }),
3606
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3607
- },
3608
- "illegal node with subject having type and property": {
3609
- input: %({
3610
- "@id": {
3611
- "@id": "ex:rei",
3612
- "@type": "ex:Type",
3613
- "ex:prop": "value"
3614
- },
3615
- "ex:prop": "value2"
3616
- }),
3617
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3618
- },
3619
- "node with embedded object": {
3620
- input: %({
3621
- "@id": "ex:subj",
3622
- "ex:value": {
3623
- "@id": {
3624
- "@id": "ex:rei",
3625
- "ex:prop": "value"
3626
- }
3627
- }
3628
- }),
3629
- output: %([{
3630
- "@id": "ex:subj",
3631
- "ex:value": [{
3632
- "@id": {
3633
- "@id": "ex:rei",
3634
- "ex:prop": [{"@value": "value"}]
3635
- }
3636
- }]
3637
- }])
3638
- },
3639
- "node with embedded object having properties": {
3640
- input: %({
3641
- "@id": "ex:subj",
3642
- "ex:value": {
3643
- "@id": {
3644
- "@id": "ex:rei",
3645
- "ex:prop": "value"
3646
- },
3647
- "ex:prop": "value2"
3648
- }
3649
- }),
3650
- output: %([{
3651
- "@id": "ex:subj",
3652
- "ex:value": [{
3653
- "@id": {
3654
- "@id": "ex:rei",
3655
- "ex:prop": [{"@value": "value"}]
3656
- },
3657
- "ex:prop": [{"@value": "value2"}]
3658
- }]
3659
- }])
3660
- },
3661
- "node with recursive embedded object": {
3662
- input: %({
3663
- "@id": "ex:subj",
3664
- "ex:value": {
3665
- "@id": {
3666
- "@id": {
3667
- "@id": "ex:rei",
3668
- "ex:prop": "value3"
3669
- },
3670
- "ex:prop": "value"
3671
- },
3672
- "ex:prop": "value2"
3673
- }
3674
- }),
3675
- output: %([{
3676
- "@id": "ex:subj",
3677
- "ex:value": [{
3678
- "@id": {
3679
- "@id": {
3680
- "@id": "ex:rei",
3681
- "ex:prop": [{"@value": "value3"}]
3682
- },
3683
- "ex:prop":[{"@value": "value"}]
3684
- },
3685
- "ex:prop": [{"@value": "value2"}]
3686
- }]
3687
- }])
3688
- },
3689
- "node with @annotation property on value object": {
3690
- input: %({
3691
- "@id": "ex:bob",
3692
- "ex:age": {
3693
- "@value": 23,
3694
- "@annotation": {"ex:certainty": 0.8}
3695
- }
3696
- }),
3697
- output: %([{
3698
- "@id": "ex:bob",
3699
- "ex:age": [{
3700
- "@value": 23,
3701
- "@annotation": [{"ex:certainty": [{"@value": 0.8}]}]
3702
- }]
3703
- }])
3704
- },
3705
- "node with @annotation property on node object": {
3706
- input: %({
3707
- "@id": "ex:bob",
3708
- "ex:name": "Bob",
3709
- "ex:knows": {
3710
- "@id": "ex:fred",
3711
- "ex:name": "Fred",
3712
- "@annotation": {"ex:certainty": 0.8}
3713
- }
3714
- }),
3715
- output: %([{
3716
- "@id": "ex:bob",
3717
- "ex:name": [{"@value": "Bob"}],
3718
- "ex:knows": [{
3719
- "@id": "ex:fred",
3720
- "ex:name": [{"@value": "Fred"}],
3721
- "@annotation": [{"ex:certainty": [{"@value": 0.8}]}]
3722
- }]
3723
- }])
3724
- },
3725
- "node with @annotation property multiple values": {
3726
- input: %({
3727
- "@id": "ex:bob",
3728
- "ex:name": "Bob",
3729
- "ex:knows": {
3730
- "@id": "ex:fred",
3731
- "ex:name": "Fred",
3732
- "@annotation": [{
3733
- "ex:certainty": 0.8
3734
- }, {
3735
- "ex:source": {"@id": "http://example.org/"}
3736
- }]
3737
- }
3738
- }),
3739
- output: %([{
3740
- "@id": "ex:bob",
3741
- "ex:name": [{"@value": "Bob"}],
3742
- "ex:knows": [{
3743
- "@id": "ex:fred",
3744
- "ex:name": [{"@value": "Fred"}],
3745
- "@annotation": [{
3746
- "ex:certainty": [{"@value": 0.8}]
3747
- }, {
3748
- "ex:source": [{"@id": "http://example.org/"}]
3749
- }]
3750
- }]
3751
- }])
3752
- },
3753
- "node with @annotation property that is on the top-level is invalid": {
3754
- input: %({
3755
- "@id": "ex:bob",
3756
- "ex:name": "Bob",
3757
- "@annotation": {"ex:prop": "value2"}
3758
- }),
3759
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3760
- },
3761
- "node with @annotation property on a top-level graph node is invalid": {
3762
- input: %({
3763
- "@id": "ex:bob",
3764
- "ex:name": "Bob",
3765
- "@graph": {
3766
- "@id": "ex:fred",
3767
- "ex:name": "Fred",
3768
- "@annotation": {"ex:prop": "value2"}
3769
- }
3770
- }),
3771
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3772
- },
3773
- "node with @annotation property having @id is invalid": {
3774
- input: %({
3775
- "@id": "ex:bob",
3776
- "ex:knows": {
3777
- "@id": "ex:fred",
3778
- "@annotation": {
3779
- "@id": "ex:invalid-ann-id",
3780
- "ex:prop": "value2"
3781
- }
3782
- }
3783
- }),
3784
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3785
- },
3786
- "node with @annotation property with value object value is invalid": {
3787
- input: %({
3788
- "@id": "ex:bob",
3789
- "ex:knows": {
3790
- "@id": "fred",
3791
- "@annotation": "value2"
3792
- }
3793
- }),
3794
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3795
- },
3796
- "node with @annotation on a list": {
3797
- input: %({
3798
- "@id": "ex:bob",
3799
- "ex:knows": {
3800
- "@list": [{"@id": "ex:fred"}],
3801
- "@annotation": {"ex:prop": "value2"}
3802
- }
3803
- }),
3804
- exception: JSON::LD::JsonLdError::InvalidSetOrListObject
3805
- },
3806
- "node with @annotation on a list value": {
3807
- input: %({
3808
- "@id": "ex:bob",
3809
- "ex:knows": {
3810
- "@list": [
3811
- {
3812
- "@id": "ex:fred",
3813
- "@annotation": {"ex:prop": "value2"}
3814
- }
3815
- ]
3816
- }
3817
- }),
3818
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3819
- },
3820
- "node with @annotation property on a top-level @included node is invalid": {
3821
- input: %({
3822
- "@id": "ex:bob",
3823
- "ex:name": "Bob",
3824
- "@included": [{
3825
- "@id": "ex:fred",
3826
- "ex:name": "Fred",
3827
- "@annotation": {"ex:prop": "value2"}
3828
- }]
3829
- }),
3830
- exception: JSON::LD::JsonLdError::InvalidAnnotation
3831
- },
3832
- "node with @annotation property on embedded subject": {
3833
- input: %({
3834
- "@id": {
3835
- "@id": "ex:rei",
3836
- "ex:prop": {"@id": "_:value"}
3837
- },
3838
- "ex:prop": {
3839
- "@value": "value2",
3840
- "@annotation": {"ex:certainty": 0.8}
3841
- }
3842
- }),
3843
- output: %([{
3844
- "@id": {
3845
- "@id": "ex:rei",
3846
- "ex:prop": [{"@id": "_:value"}]
3847
- },
3848
- "ex:prop": [{
3849
- "@value": "value2",
3850
- "@annotation": [{
3851
- "ex:certainty": [{"@value": 0.8}]
3852
- }]
3853
- }]
3854
- }])
3855
- },
3856
- "node with @annotation property on embedded object": {
3857
- input: %({
3858
- "@id": "ex:subj",
3859
- "ex:value": {
3860
- "@id": {
3861
- "@id": "ex:rei",
3862
- "ex:prop": "value"
3863
- },
3864
- "@annotation": {"ex:certainty": 0.8}
3865
- }
3866
- }),
3867
- output: %([{
3868
- "@id": "ex:subj",
3869
- "ex:value": [{
3870
- "@id": {
3871
- "@id": "ex:rei",
3872
- "ex:prop": [{"@value": "value"}]
3873
- },
3874
- "@annotation": [{
3875
- "ex:certainty": [{"@value": 0.8}]
3876
- }]
3877
- }]
3878
- }])
3879
- },
3880
- "embedded node with reverse relationship": {
3881
- input: %({
3882
- "@context": {
3883
- "rel": {"@reverse": "ex:rel"}
3884
- },
3885
- "@id": {
3886
- "@id": "ex:rei",
3887
- "rel": {"@id": "ex:value"}
3888
- },
3889
- "ex:prop": "value2"
3890
- }),
3891
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3892
- },
3893
- "embedded node with expanded reverse relationship": {
3894
- input: %({
3895
- "@id": {
3896
- "@id": "ex:rei",
3897
- "@reverse": {
3898
- "ex:rel": {"@id": "ex:value"}
3899
- }
3900
- },
3901
- "ex:prop": "value2"
3902
- }),
3903
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
3904
- },
3905
- "embedded node used as subject in reverse relationship": {
3906
- input: %({
3907
- "@context": {
3908
- "rel": {"@reverse": "ex:rel"}
3909
- },
3910
- "@id": {
3911
- "@id": "ex:rei",
3912
- "ex:prop": {"@id": "ex:value"}
3913
- },
3914
- "rel": {"@id": "ex:value2"}
3915
- }),
3916
- output: %([{
3917
- "@id": {
3918
- "@id": "ex:rei",
3919
- "ex:prop": [{"@id": "ex:value"}]
3920
- },
3921
- "@reverse": {
3922
- "ex:rel": [{"@id": "ex:value2"}]
3923
- }
3924
- }])
3925
- },
3926
- "embedded node used as object in reverse relationship": {
3927
- input: %({
3928
- "@context": {
3929
- "rel": {"@reverse": "ex:rel"}
3930
- },
3931
- "@id": "ex:subj",
3932
- "rel": {
3933
- "@id": {
3934
- "@id": "ex:rei",
3935
- "ex:prop": {"@id": "ex:value"}
3936
- },
3937
- "ex:prop": {"@id": "ex:value2"}
3938
- }
3939
- }),
3940
- output: %([{
3941
- "@id": "ex:subj",
3942
- "@reverse": {
3943
- "ex:rel": [{
3944
- "@id": {
3945
- "@id": "ex:rei",
3946
- "ex:prop": [{"@id": "ex:value"}]
3947
- },
3948
- "ex:prop": [{"@id": "ex:value2"}]
3949
- }]
3950
- }
3951
- }])
3952
- },
3953
- "node with @annotation property on node object with reverse relationship": {
3954
- input: %({
3955
- "@context": {
3956
- "knownBy": {"@reverse": "ex:knows"}
3957
- },
3958
- "@id": "ex:bob",
3959
- "ex:name": "Bob",
3960
- "knownBy": {
3961
- "@id": "ex:fred",
3962
- "ex:name": "Fred",
3963
- "@annotation": {"ex:certainty": 0.8}
3964
- }
3965
- }),
3966
- output: %([{
3967
- "@id": "ex:bob",
3968
- "ex:name": [{"@value": "Bob"}],
3969
- "@reverse": {
3970
- "ex:knows": [{
3971
- "@id": "ex:fred",
3972
- "ex:name": [{"@value": "Fred"}],
3973
- "@annotation": [{"ex:certainty": [{"@value": 0.8}]}]
3974
- }]
3975
- }
3976
- }])
3977
- },
3978
- "reverse relationship inside annotation": {
3979
- input: %({
3980
- "@context": {
3981
- "claims": {"@reverse": "ex:claims", "@type": "@id"}
3982
- },
3983
- "@id": "ex:bob",
3984
- "ex:knows": {
3985
- "@id": "ex:jane",
3986
- "@annotation": {
3987
- "ex:certainty": 0.8,
3988
- "claims": "ex:sue"
3989
- }
3990
- }
3991
- }),
3992
- output: %([{
3993
- "@id": "ex:bob",
3994
- "ex:knows": [{
3995
- "@id": "ex:jane",
3996
- "@annotation": [{
3997
- "ex:certainty": [{"@value": 0.8}],
3998
- "@reverse": {
3999
- "ex:claims": [{"@id": "ex:sue"}]
4000
- }
4001
- }]
4002
- }]
4003
- }])
4004
- },
4005
- }.each do |title, params|
4006
- it(title) {run_expand params.merge(rdfstar: true)}
4007
- end
4008
- end
4009
-
4010
- begin
4011
- require 'nokogiri'
4012
- rescue LoadError
4013
- end
4014
- require 'rexml/document'
4015
-
4016
- context "html" do
4017
- %w(Nokogiri REXML).each do |impl|
4018
- next unless Module.constants.map(&:to_s).include?(impl)
4019
- context impl do
4020
- let(:library) {impl.downcase.to_s.to_sym}
4021
-
4022
- {
4023
- "Expands embedded JSON-LD script element": {
4024
- input: %(
4025
- <html>
4026
- <head>
4027
- <script type="application/ld+json">
4028
- {
4029
- "@context": {
4030
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4031
- },
4032
- "foo": [{"@value": "bar"}]
4033
- }
4034
- </script>
4035
- </head>
4036
- </html>),
4037
- output: %([{
4038
- "http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
4039
- }])
4040
- },
4041
- "Expands first script element": {
4042
- input: %(
4043
- <html>
4044
- <head>
4045
- <script type="application/ld+json">
4046
- {
4047
- "@context": {
4048
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4049
- },
4050
- "foo": [{"@value": "bar"}]
4051
- }
4052
- </script>
4053
- <script type="application/ld+json">
4054
- {
4055
- "@context": {"ex": "http://example.com/"},
4056
- "@graph": [
4057
- {"ex:foo": {"@value": "foo"}},
4058
- {"ex:bar": {"@value": "bar"}}
4059
- ]
4060
- }
4061
- </script>
4062
- </head>
4063
- </html>),
4064
- output: %([{
4065
- "http://example.com/foo": [{"@list": [{"@value": "bar"}]}]
4066
- }])
4067
- },
4068
- "Expands targeted script element": {
4069
- input: %(
4070
- <html>
4071
- <head>
4072
- <script id="first" type="application/ld+json">
4073
- {
4074
- "@context": {
4075
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4076
- },
4077
- "foo": [{"@value": "bar"}]
4078
- }
4079
- </script>
4080
- <script id="second" type="application/ld+json">
4081
- {
4082
- "@context": {"ex": "http://example.com/"},
4083
- "@graph": [
4084
- {"ex:foo": {"@value": "foo"}},
4085
- {"ex:bar": {"@value": "bar"}}
4086
- ]
4087
- }
4088
- </script>
4089
- </head>
4090
- </html>),
4091
- output: %([
4092
- {"http://example.com/foo": [{"@value": "foo"}]},
4093
- {"http://example.com/bar": [{"@value": "bar"}]}
4094
- ]),
4095
- base: "http://example.org/doc#second"
4096
- },
4097
- "Expands all script elements with extractAllScripts option": {
4098
- input: %(
4099
- <html>
4100
- <head>
4101
- <script type="application/ld+json">
4102
- {
4103
- "@context": {
4104
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4105
- },
4106
- "foo": [{"@value": "bar"}]
4107
- }
4108
- </script>
4109
- <script type="application/ld+json">
4110
- {
4111
- "@context": {"ex": "http://example.com/"},
4112
- "@graph": [
4113
- {"ex:foo": {"@value": "foo"}},
4114
- {"ex:bar": {"@value": "bar"}}
4115
- ]
4116
- }
4117
- </script>
4118
- </head>
4119
- </html>),
4120
- output: %([
4121
- {"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]},
4122
- {
4123
- "@graph": [{
4124
- "http://example.com/foo": [{"@value": "foo"}]
4125
- }, {
4126
- "http://example.com/bar": [{"@value": "bar"}]
4127
- }]
4128
- }
4129
- ]),
4130
- extractAllScripts: true
4131
- },
4132
- "Expands multiple scripts where one is an array": {
4133
- input: %(
4134
- <html>
4135
- <head>
4136
- <script type="application/ld+json">
4137
- {
4138
- "@context": {
4139
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4140
- },
4141
- "foo": [{"@value": "bar"}]
4142
- }
4143
- </script>
4144
- <script type="application/ld+json">
4145
- [
4146
- {"@context": {"ex": "http://example.com/"}, "ex:foo": {"@value": "foo"}},
4147
- {"@context": {"ex": "http://example.com/"}, "ex:bar": {"@value": "bar"}}
4148
- ]
4149
- </script>
4150
- </head>
4151
- </html>),
4152
- output: %([
4153
- {"http://example.com/foo": [{"@list": [{"@value": "bar"}]}]},
4154
- {"http://example.com/foo": [{"@value": "foo"}]},
4155
- {"http://example.com/bar": [{"@value": "bar"}]}
4156
- ]),
4157
- extractAllScripts: true
4158
- },
4159
- "Errors no script element": {
4160
- input: %(<html><head></head></html>),
4161
- exception: JSON::LD::JsonLdError::LoadingDocumentFailed
4162
- },
4163
- "Expands as empty with no script element and extractAllScripts": {
4164
- input: %(<html><head></head></html>),
4165
- output: %([]),
4166
- extractAllScripts: true
4167
- },
4168
- "Expands script element with HTML character references": {
4169
- input: %(
4170
- <html>
4171
- <head>
4172
- <script type="application/ld+json">
4173
- {
4174
- "@context": {"@vocab": "http://example/"},
4175
- "foo": "&lt;&amp;&gt;"
4176
- }
4177
- </script>
4178
- </head>
4179
- </html>),
4180
- output: %([{
4181
- "http://example/foo": [{"@value": "&lt;&amp;&gt;"}]
4182
- }])
4183
- },
4184
- "Expands embedded JSON-LD script element relative to document base": {
4185
- input: %(
4186
- <html>
4187
- <head>
4188
- <script type="application/ld+json">
4189
- {
4190
- "@context": {
4191
- "foo": {"@id": "http://example.com/foo"}
4192
- },
4193
- "@id": "",
4194
- "foo": [{"@value": "bar"}]
4195
- }
4196
- </script>
4197
- </head>
4198
- </html>),
4199
- output: %([{
4200
- "@id": "http://example.org/doc",
4201
- "http://example.com/foo": [{"@value": "bar"}]
4202
- }]),
4203
- base: "http://example.org/doc"
4204
- },
4205
- "Expands embedded JSON-LD script element relative to HTML base": {
4206
- input: %(
4207
- <html>
4208
- <head>
4209
- <base href="http://example.org/base" />
4210
- <script type="application/ld+json">
4211
- {
4212
- "@context": {
4213
- "foo": {"@id": "http://example.com/foo"}
4214
- },
4215
- "@id": "",
4216
- "foo": [{"@value": "bar"}]
4217
- }
4218
- </script>
4219
- </head>
4220
- </html>),
4221
- output: %([{
4222
- "@id": "http://example.org/base",
4223
- "http://example.com/foo": [{"@value": "bar"}]
4224
- }]),
4225
- base: "http://example.org/doc"
4226
- },
4227
- "Expands embedded JSON-LD script element relative to relative HTML base": {
4228
- input: %(
4229
- <html>
4230
- <head>
4231
- <base href="base" />
4232
- <script type="application/ld+json">
4233
- {
4234
- "@context": {
4235
- "foo": {"@id": "http://example.com/foo"}
4236
- },
4237
- "@id": "",
4238
- "foo": [{"@value": "bar"}]
4239
- }
4240
- </script>
4241
- </head>
4242
- </html>),
4243
- output: %([{
4244
- "@id": "http://example.org/base",
4245
- "http://example.com/foo": [{"@value": "bar"}]
4246
- }]),
4247
- base: "http://example.org/doc"
4248
- },
4249
- "Errors if no element found at target": {
4250
- input: %(
4251
- <html>
4252
- <head>
4253
- <script id="first" type="application/ld+json">
4254
- {
4255
- "@context": {
4256
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4257
- },
4258
- "foo": [{"@value": "bar"}]
4259
- }
4260
- </script>
4261
- <script id="second" type="application/ld+json">
4262
- {
4263
- "@context": {"ex": "http://example.com/"},
4264
- "@graph": [
4265
- {"ex:foo": {"@value": "foo"}},
4266
- {"ex:bar": {"@value": "bar"}}
4267
- ]
4268
- }
4269
- </script>
4270
- </head>
4271
- </html>),
4272
- base: "http://example.org/doc#third",
4273
- exception: JSON::LD::JsonLdError::LoadingDocumentFailed
4274
- },
4275
- "Errors if targeted element is not a script element": {
4276
- input: %(
4277
- <html>
4278
- <head>
4279
- <pre id="first" type="application/ld+json">
4280
- {
4281
- "@context": {
4282
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4283
- },
4284
- "foo": [{"@value": "bar"}]
4285
- }
4286
- </pre>
4287
- </head>
4288
- </html>),
4289
- base: "http://example.org/doc#first",
4290
- exception: JSON::LD::JsonLdError::LoadingDocumentFailed
4291
- },
4292
- "Errors if targeted element does not have type application/ld+json": {
4293
- input: %(
4294
- <html>
4295
- <head>
4296
- <script id="first" type="application/json">
4297
- {
4298
- "@context": {
4299
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4300
- },
4301
- "foo": [{"@value": "bar"}]
4302
- }
4303
- </script>
4304
- </head>
4305
- </html>),
4306
- base: "http://example.org/doc#first",
4307
- exception: JSON::LD::JsonLdError::LoadingDocumentFailed
4308
- },
4309
- "Errors if uncommented script text contains comment": {
4310
- input: %(
4311
- <html>
4312
- <head>
4313
- <script type="application/ld+json">
4314
- <!--
4315
- {
4316
- "@context": {
4317
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4318
- },
4319
- "foo": [{"@value": "<!-- -->"}]
4320
- }
4321
- -->
4322
- </script>
4323
- </head>
4324
- </html>),
4325
- exception: JSON::LD::JsonLdError::InvalidScriptElement,
4326
- not: :rexml
4327
- },
4328
- "Errors if end comment missing": {
4329
- input: %(
4330
- <html>
4331
- <head>
4332
- <script type="application/ld+json">
4333
- <!--
4334
- {
4335
- "@context": {
4336
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4337
- },
4338
- "foo": [{"@value": "bar"}]
4339
- }
4340
- </script>
4341
- </head>
4342
- </html>),
4343
- exception: JSON::LD::JsonLdError::InvalidScriptElement,
4344
- not: :rexml
4345
- },
4346
- "Errors if start comment missing": {
4347
- input: %(
4348
- <html>
4349
- <head>
4350
- <script type="application/ld+json">
4351
- {
4352
- "@context": {
4353
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
4354
- },
4355
- "foo": [{"@value": "bar"}]
4356
- }
4357
- -->
4358
- </script>
4359
- </head>
4360
- </html>),
4361
- exception: JSON::LD::JsonLdError::InvalidScriptElement
4362
- },
4363
- "Errors if uncommented script is not valid JSON": {
4364
- input: %(
4365
- <html>
4366
- <head>
4367
- <script type="application/ld+json">
4368
- foo
4369
- </script>
4370
- </head>
4371
- </html>),
4372
- exception: JSON::LD::JsonLdError::InvalidScriptElement
4373
- },
4374
- }.each do |title, params|
4375
- it(title) do
4376
- skip "rexml" if params[:not] == library
4377
- params = params.merge(input: StringIO.new(params[:input]))
4378
- params[:input].send(:define_singleton_method, :content_type) {"text/html"}
4379
- run_expand params.merge(validate: true, library: library)
4380
- end
4381
- end
4382
- end
4383
- end
4384
- end
4385
-
4386
- context "deprectaions" do
4387
- {
4388
- "blank node property": {
4389
- input: %({"_:bn": "value"}),
4390
- output: %([{"_:bn": [{"@value": "value"}]}])
4391
- }
4392
- }.each do |name, params|
4393
- it "deprecation on #{name} when validating" do
4394
- run_expand(params.merge(validate: true, write: "[DEPRECATION]"))
4395
- end
4396
-
4397
- it "no deprecation on #{name} when not validating" do
4398
- run_expand(params.merge(validate: false))
4399
- end
4400
- end
4401
- end
4402
-
4403
- context "exceptions" do
4404
- {
4405
- "non-null @value and null @type": {
4406
- input: %({"http://example.com/foo": {"@value": "foo", "@type": null}}),
4407
- exception: JSON::LD::JsonLdError::InvalidTypeValue
4408
- },
4409
- "non-null @value and null @language": {
4410
- input: %({"http://example.com/foo": {"@value": "foo", "@language": null}}),
4411
- exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString
4412
- },
4413
- "value with null language": {
4414
- input: %({
4415
- "@context": {"@language": "en"},
4416
- "http://example.org/nolang": {"@value": "no language", "@language": null}
4417
- }),
4418
- exception: JSON::LD::JsonLdError::InvalidLanguageTaggedString
4419
- },
4420
- "colliding keywords": {
4421
- input: %({
4422
- "@context": {
4423
- "id": "@id",
4424
- "ID": "@id"
4425
- },
4426
- "id": "http://example/foo",
4427
- "ID": "http://example/bar"
4428
- }),
4429
- exception: JSON::LD::JsonLdError::CollidingKeywords,
4430
- },
4431
- "@language and @type": {
4432
- input: %({
4433
- "ex:p": {
4434
- "@value": "v",
4435
- "@type": "ex:t",
4436
- "@language": "en"
4437
- }
4438
- }),
4439
- exception: JSON::LD::JsonLdError::InvalidValueObject,
4440
- processingMode: 'json-ld-1.1'
4441
- },
4442
- "@direction and @type": {
4443
- input: %({
4444
- "ex:p": {
4445
- "@value": "v",
4446
- "@type": "ex:t",
4447
- "@direction": "rtl"
4448
- }
4449
- }),
4450
- exception: JSON::LD::JsonLdError::InvalidValueObject,
4451
- processingMode: 'json-ld-1.1'
4452
- },
4453
- }.each do |title, params|
4454
- it(title) {run_expand params}
4455
- end
4456
- end
4457
-
4458
- context "problem cases" do
4459
- {
4460
- "toRdf/0118": {
4461
- input: %({
4462
- "@context": {"term": "_:term", "termId": { "@id": "term", "@type": "@id" }},
4463
- "termId": "term:AppendedToBlankNode"
4464
- }),
4465
- output: %([{
4466
- "_:term": [{"@id": "_:termAppendedToBlankNode"}]
4467
- }])
4468
- },
4469
- }.each do |title, params|
4470
- it(title) {run_expand params}
4471
- end
4472
- end
4473
- end
4474
-
4475
- def run_expand(params)
4476
- input, output = params[:input], params[:output]
4477
- params[:base] ||= nil
4478
- input = ::JSON.parse(input) if input.is_a?(String)
4479
- output = ::JSON.parse(output) if output.is_a?(String)
4480
- pending params.fetch(:pending, "test implementation") unless input
4481
- if params[:exception]
4482
- expect {JSON::LD::API.expand(input, **params)}.to raise_error(params[:exception])
4483
- else
4484
- jld = nil
4485
- if params[:write]
4486
- expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.to write(params[:write]).to(:error)
4487
- else
4488
- expect{jld = JSON::LD::API.expand(input, logger: logger, **params)}.not_to write.to(:error)
4489
- end
4490
- expect(jld).to produce_jsonld(output, logger)
4491
-
4492
- # Also expect result to produce itself
4493
- expect(output).to produce_jsonld(output, logger)
4494
- end
4495
- end
4496
- end