json-ld 3.2.4 → 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/json/ld/api.rb +807 -771
  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 -1913
  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 +223 -204
  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 -169
  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 +55 -198
  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 -2056
  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 -2541
  33. data/spec/from_rdf_spec.rb +0 -1072
  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 -1684
  99. data/spec/writer_spec.rb +0 -427
data/spec/flatten_spec.rb DELETED
@@ -1,1203 +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 ".flatten" do
8
- {
9
- "single object": {
10
- input: %({"@id": "http://example.com", "@type": "http://www.w3.org/2000/01/rdf-schema#Resource"}),
11
- output: %([
12
- {"@id": "http://example.com", "@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"]}
13
- ])
14
- },
15
- "embedded object": {
16
- input: %({
17
- "@context": {
18
- "foaf": "http://xmlns.com/foaf/0.1/"
19
- },
20
- "@id": "http://greggkellogg.net/foaf",
21
- "@type": "http://xmlns.com/foaf/0.1/PersonalProfileDocument",
22
- "foaf:primaryTopic": [{
23
- "@id": "http://greggkellogg.net/foaf#me",
24
- "@type": "http://xmlns.com/foaf/0.1/Person"
25
- }]
26
- }),
27
- output: %([
28
- {
29
- "@id": "http://greggkellogg.net/foaf",
30
- "@type": ["http://xmlns.com/foaf/0.1/PersonalProfileDocument"],
31
- "http://xmlns.com/foaf/0.1/primaryTopic": [{"@id": "http://greggkellogg.net/foaf#me"}]
32
- },
33
- {
34
- "@id": "http://greggkellogg.net/foaf#me",
35
- "@type": ["http://xmlns.com/foaf/0.1/Person"]
36
- }
37
- ])
38
- },
39
- "embedded anon": {
40
- input: %({
41
- "@context": {
42
- "foaf": "http://xmlns.com/foaf/0.1/"
43
- },
44
- "@id": "http://greggkellogg.net/foaf",
45
- "@type": "foaf:PersonalProfileDocument",
46
- "foaf:primaryTopic": {
47
- "@type": "foaf:Person"
48
- }
49
- }),
50
- output: %([
51
- {
52
- "@id": "_:b0",
53
- "@type": ["http://xmlns.com/foaf/0.1/Person"]
54
- },
55
- {
56
- "@id": "http://greggkellogg.net/foaf",
57
- "@type": ["http://xmlns.com/foaf/0.1/PersonalProfileDocument"],
58
- "http://xmlns.com/foaf/0.1/primaryTopic": [{"@id": "_:b0"}]
59
- }
60
- ])
61
- },
62
- "reverse properties": {
63
- input: %([
64
- {
65
- "@id": "http://example.com/people/markus",
66
- "@reverse": {
67
- "http://xmlns.com/foaf/0.1/knows": [
68
- {
69
- "@id": "http://example.com/people/dave"
70
- },
71
- {
72
- "@id": "http://example.com/people/gregg"
73
- }
74
- ]
75
- },
76
- "http://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ]
77
- }
78
- ]),
79
- output: %([
80
- {
81
- "@id": "http://example.com/people/dave",
82
- "http://xmlns.com/foaf/0.1/knows": [
83
- {
84
- "@id": "http://example.com/people/markus"
85
- }
86
- ]
87
- },
88
- {
89
- "@id": "http://example.com/people/gregg",
90
- "http://xmlns.com/foaf/0.1/knows": [
91
- {
92
- "@id": "http://example.com/people/markus"
93
- }
94
- ]
95
- },
96
- {
97
- "@id": "http://example.com/people/markus",
98
- "http://xmlns.com/foaf/0.1/name": [
99
- {
100
- "@value": "Markus Lanthaler"
101
- }
102
- ]
103
- }
104
- ])
105
- },
106
- "Simple named graph (Wikidata)": {
107
- input: %q({
108
- "@context": {
109
- "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
110
- "ex": "http://example.org/",
111
- "xsd": "http://www.w3.org/2001/XMLSchema#",
112
- "ex:locatedIn": {"@type": "@id"},
113
- "ex:hasPopulaton": {"@type": "xsd:integer"},
114
- "ex:hasReference": {"@type": "@id"}
115
- },
116
- "@graph": [
117
- {
118
- "@id": "http://example.org/ParisFact1",
119
- "@type": "rdf:Graph",
120
- "@graph": {
121
- "@id": "http://example.org/location/Paris#this",
122
- "ex:locatedIn": "http://example.org/location/France#this"
123
- },
124
- "ex:hasReference": ["http://www.britannica.com/", "http://www.wikipedia.org/", "http://www.brockhaus.de/"]
125
- },
126
- {
127
- "@id": "http://example.org/ParisFact2",
128
- "@type": "rdf:Graph",
129
- "@graph": {
130
- "@id": "http://example.org/location/Paris#this",
131
- "ex:hasPopulation": 7000000
132
- },
133
- "ex:hasReference": "http://www.wikipedia.org/"
134
- }
135
- ]
136
- }),
137
- output: %q([{
138
- "@id": "http://example.org/ParisFact1",
139
- "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"],
140
- "http://example.org/hasReference": [
141
- {"@id": "http://www.britannica.com/"},
142
- {"@id": "http://www.wikipedia.org/"},
143
- {"@id": "http://www.brockhaus.de/"}
144
- ],
145
- "@graph": [{
146
- "@id": "http://example.org/location/Paris#this",
147
- "http://example.org/locatedIn": [{"@id": "http://example.org/location/France#this"}]
148
- }]
149
- }, {
150
- "@id": "http://example.org/ParisFact2",
151
- "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"],
152
- "http://example.org/hasReference": [{"@id": "http://www.wikipedia.org/"}],
153
- "@graph": [{
154
- "@id": "http://example.org/location/Paris#this",
155
- "http://example.org/hasPopulation": [{"@value": 7000000}]
156
- }]
157
- }]),
158
- },
159
- "Test Manifest (shortened)": {
160
- input: %q{
161
- {
162
- "@id": "",
163
- "http://example/sequence": {"@list": [
164
- {
165
- "@id": "#t0001",
166
- "http://example/name": "Keywords cannot be aliased to other keywords",
167
- "http://example/input": {"@id": "error-expand-0001-in.jsonld"}
168
- }
169
- ]}
170
- }
171
- },
172
- output: %q{
173
- [{
174
- "@id": "",
175
- "http://example/sequence": [{"@list": [{"@id": "#t0001"}]}]
176
- }, {
177
- "@id": "#t0001",
178
- "http://example/input": [{"@id": "error-expand-0001-in.jsonld"}],
179
- "http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}]
180
- }]
181
- },
182
- },
183
- "@reverse bnode issue (0045)": {
184
- input: %q{
185
- {
186
- "@context": {
187
- "foo": "http://example.org/foo",
188
- "bar": { "@reverse": "http://example.org/bar", "@type": "@id" }
189
- },
190
- "foo": "Foo",
191
- "bar": [ "http://example.org/origin", "_:b0" ]
192
- }
193
- },
194
- output: %q{
195
- [
196
- {
197
- "@id": "_:b0",
198
- "http://example.org/foo": [ { "@value": "Foo" } ]
199
- },
200
- {
201
- "@id": "_:b1",
202
- "http://example.org/bar": [ { "@id": "_:b0" } ]
203
- },
204
- {
205
- "@id": "http://example.org/origin",
206
- "http://example.org/bar": [ { "@id": "_:b0" } ]
207
- }
208
- ]
209
- },
210
- remap_nodes: true
211
- },
212
- "@list with embedded object": {
213
- input: %([{
214
- "http://example.com/foo": [{
215
- "@list": [{
216
- "@id": "http://example.com/baz",
217
- "http://example.com/bar": "buz"}
218
- ]}
219
- ]}
220
- ]),
221
- output: %([
222
- {
223
- "@id": "_:b0",
224
- "http://example.com/foo": [{
225
- "@list": [
226
- {
227
- "@id": "http://example.com/baz"
228
- }
229
- ]
230
- }]
231
- },
232
- {
233
- "@id": "http://example.com/baz",
234
- "http://example.com/bar": [{"@value": "buz"}]
235
- }
236
- ])
237
- },
238
- "coerced @list containing an deep list": {
239
- input: %([{
240
- "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
241
- }]),
242
- output: %([{
243
- "@id": "_:b0",
244
- "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
245
- }]),
246
- },
247
- "@list containing empty @list": {
248
- input: %({
249
- "http://example.com/foo": {"@list": [{"@list": []}]}
250
- }),
251
- output: %([{
252
- "@id": "_:b0",
253
- "http://example.com/foo": [{"@list": [{"@list": []}]}]
254
- }])
255
- },
256
- "coerced @list containing mixed list values": {
257
- input: %({
258
- "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
259
- "foo": [
260
- [{"@id": "http://example/a", "@type": "http://example/Bar"}],
261
- {"@id": "http://example/b", "@type": "http://example/Baz"}]
262
- }),
263
- output: %([{
264
- "@id": "_:b0",
265
- "http://example.com/foo": [{"@list": [
266
- {"@list": [{"@id": "http://example/a"}]},
267
- {"@id": "http://example/b"}
268
- ]}]
269
- },
270
- {
271
- "@id": "http://example/a",
272
- "@type": [
273
- "http://example/Bar"
274
- ]
275
- },
276
- {
277
- "@id": "http://example/b",
278
- "@type": [
279
- "http://example/Baz"
280
- ]
281
- }])
282
- },
283
- }.each do |title, params|
284
- it(title) {run_flatten(params)}
285
- end
286
-
287
- context "@included" do
288
- {
289
- "Basic Included array": {
290
- input: %({
291
- "@context": {
292
- "@version": 1.1,
293
- "@vocab": "http://example.org/"
294
- },
295
- "prop": "value",
296
- "@included": [{
297
- "prop": "value2"
298
- }]
299
- }),
300
- output: %([{
301
- "@id": "_:b0",
302
- "http://example.org/prop": [{"@value": "value"}]
303
- }, {
304
- "@id": "_:b1",
305
- "http://example.org/prop": [{"@value": "value2"}]
306
- }])
307
- },
308
- "Basic Included object": {
309
- input: %({
310
- "@context": {
311
- "@version": 1.1,
312
- "@vocab": "http://example.org/"
313
- },
314
- "prop": "value",
315
- "@included": {
316
- "prop": "value2"
317
- }
318
- }),
319
- output: %([{
320
- "@id": "_:b0",
321
- "http://example.org/prop": [{"@value": "value"}]
322
- }, {
323
- "@id": "_:b1",
324
- "http://example.org/prop": [{"@value": "value2"}]
325
- }])
326
- },
327
- "Multiple properties mapping to @included are folded together": {
328
- input: %({
329
- "@context": {
330
- "@version": 1.1,
331
- "@vocab": "http://example.org/",
332
- "included1": "@included",
333
- "included2": "@included"
334
- },
335
- "included1": {"prop": "value1"},
336
- "included2": {"prop": "value2"}
337
- }),
338
- output: %([{
339
- "@id": "_:b1",
340
- "http://example.org/prop": [{"@value": "value1"}]
341
- }, {
342
- "@id": "_:b2",
343
- "http://example.org/prop": [{"@value": "value2"}]
344
- }])
345
- },
346
- "Included containing @included": {
347
- input: %({
348
- "@context": {
349
- "@version": 1.1,
350
- "@vocab": "http://example.org/"
351
- },
352
- "prop": "value",
353
- "@included": {
354
- "prop": "value2",
355
- "@included": {
356
- "prop": "value3"
357
- }
358
- }
359
- }),
360
- output: %([{
361
- "@id": "_:b0",
362
- "http://example.org/prop": [{"@value": "value"}]
363
- }, {
364
- "@id": "_:b1",
365
- "http://example.org/prop": [{"@value": "value2"}]
366
- }, {
367
- "@id": "_:b2",
368
- "http://example.org/prop": [{"@value": "value3"}]
369
- }])
370
- },
371
- "Property value with @included": {
372
- input: %({
373
- "@context": {
374
- "@version": 1.1,
375
- "@vocab": "http://example.org/"
376
- },
377
- "prop": {
378
- "@type": "Foo",
379
- "@included": {
380
- "@type": "Bar"
381
- }
382
- }
383
- }),
384
- output: %([{
385
- "@id": "_:b0",
386
- "http://example.org/prop": [
387
- {"@id": "_:b1"}
388
- ]
389
- }, {
390
- "@id": "_:b1",
391
- "@type": ["http://example.org/Foo"]
392
- }, {
393
- "@id": "_:b2",
394
- "@type": ["http://example.org/Bar"]
395
- }])
396
- },
397
- "json.api example": {
398
- input: %({
399
- "@context": {
400
- "@version": 1.1,
401
- "@vocab": "http://example.org/vocab#",
402
- "@base": "http://example.org/base/",
403
- "id": "@id",
404
- "type": "@type",
405
- "data": "@nest",
406
- "attributes": "@nest",
407
- "links": "@nest",
408
- "relationships": "@nest",
409
- "included": "@included",
410
- "self": {"@type": "@id"},
411
- "related": {"@type": "@id"},
412
- "comments": {
413
- "@context": {
414
- "data": null
415
- }
416
- }
417
- },
418
- "data": [{
419
- "type": "articles",
420
- "id": "1",
421
- "attributes": {
422
- "title": "JSON:API paints my bikeshed!"
423
- },
424
- "links": {
425
- "self": "http://example.com/articles/1"
426
- },
427
- "relationships": {
428
- "author": {
429
- "links": {
430
- "self": "http://example.com/articles/1/relationships/author",
431
- "related": "http://example.com/articles/1/author"
432
- },
433
- "data": { "type": "people", "id": "9" }
434
- },
435
- "comments": {
436
- "links": {
437
- "self": "http://example.com/articles/1/relationships/comments",
438
- "related": "http://example.com/articles/1/comments"
439
- },
440
- "data": [
441
- { "type": "comments", "id": "5" },
442
- { "type": "comments", "id": "12" }
443
- ]
444
- }
445
- }
446
- }],
447
- "included": [{
448
- "type": "people",
449
- "id": "9",
450
- "attributes": {
451
- "first-name": "Dan",
452
- "last-name": "Gebhardt",
453
- "twitter": "dgeb"
454
- },
455
- "links": {
456
- "self": "http://example.com/people/9"
457
- }
458
- }, {
459
- "type": "comments",
460
- "id": "5",
461
- "attributes": {
462
- "body": "First!"
463
- },
464
- "relationships": {
465
- "author": {
466
- "data": { "type": "people", "id": "2" }
467
- }
468
- },
469
- "links": {
470
- "self": "http://example.com/comments/5"
471
- }
472
- }, {
473
- "type": "comments",
474
- "id": "12",
475
- "attributes": {
476
- "body": "I like XML better"
477
- },
478
- "relationships": {
479
- "author": {
480
- "data": { "type": "people", "id": "9" }
481
- }
482
- },
483
- "links": {
484
- "self": "http://example.com/comments/12"
485
- }
486
- }]
487
- }),
488
- output: %([{
489
- "@id": "_:b0",
490
- "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/comments"}
491
- ],
492
- "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/comments"}]
493
- }, {
494
- "@id": "http://example.org/base/1",
495
- "@type": ["http://example.org/vocab#articles"],
496
- "http://example.org/vocab#title": [{"@value": "JSON:API paints my bikeshed!"}],
497
- "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1"}],
498
- "http://example.org/vocab#author": [{"@id": "http://example.org/base/9"}],
499
- "http://example.org/vocab#comments": [{"@id": "_:b0"}]
500
- }, {
501
- "@id": "http://example.org/base/12",
502
- "@type": ["http://example.org/vocab#comments"],
503
- "http://example.org/vocab#body": [{"@value": "I like XML better"}],
504
- "http://example.org/vocab#author": [{"@id": "http://example.org/base/9"}],
505
- "http://example.org/vocab#self": [{"@id": "http://example.com/comments/12"}]
506
- }, {
507
- "@id": "http://example.org/base/2",
508
- "@type": ["http://example.org/vocab#people"]
509
- }, {
510
- "@id": "http://example.org/base/5",
511
- "@type": ["http://example.org/vocab#comments"],
512
- "http://example.org/vocab#body": [{"@value": "First!"}
513
- ],
514
- "http://example.org/vocab#author": [{"@id": "http://example.org/base/2"}],
515
- "http://example.org/vocab#self": [{"@id": "http://example.com/comments/5"}]
516
- }, {
517
- "@id": "http://example.org/base/9",
518
- "@type": ["http://example.org/vocab#people"],
519
- "http://example.org/vocab#first-name": [{"@value": "Dan"}],
520
- "http://example.org/vocab#last-name": [{"@value": "Gebhardt"}],
521
- "http://example.org/vocab#twitter": [{"@value": "dgeb"}],
522
- "http://example.org/vocab#self": [
523
- {"@id": "http://example.com/people/9"},
524
- {"@id": "http://example.com/articles/1/relationships/author"}
525
- ],
526
- "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/author"}]
527
- }])
528
- },
529
- }.each do |title, params|
530
- it(title) {run_flatten(params)}
531
- end
532
- end
533
- end
534
-
535
- context "html" do
536
- {
537
- "Flattens embedded JSON-LD script element": {
538
- input: %(
539
- <html>
540
- <head>
541
- <script type="application/ld+json">
542
- {
543
- "@context": {
544
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
545
- },
546
- "foo": [{"@value": "bar"}]
547
- }
548
- </script>
549
- </head>
550
- </html>),
551
- context: %({"foo": {"@id": "http://example.com/foo", "@container": "@list"}}),
552
- output: %({
553
- "@context": {
554
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
555
- },
556
- "@graph": [{"@id": "_:b0","foo": ["bar"]}]
557
- })
558
- },
559
- "Flattens first script element with extractAllScripts: false": {
560
- input: %(
561
- <html>
562
- <head>
563
- <script type="application/ld+json">
564
- {
565
- "@context": {
566
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
567
- },
568
- "foo": [{"@value": "bar"}]
569
- }
570
- </script>
571
- <script type="application/ld+json">
572
- {
573
- "@context": {"ex": "http://example.com/"},
574
- "@graph": [
575
- {"ex:foo": {"@value": "foo"}},
576
- {"ex:bar": {"@value": "bar"}}
577
- ]
578
- }
579
- </script>
580
- </head>
581
- </html>),
582
- context: %({"foo": {"@id": "http://example.com/foo", "@container": "@list"}}),
583
- output: %({
584
- "@context": {
585
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
586
- },
587
- "@graph": [{"@id": "_:b0","foo": ["bar"]}]
588
- }),
589
- extractAllScripts: false
590
- },
591
- "Flattens targeted script element": {
592
- input: %(
593
- <html>
594
- <head>
595
- <script id="first" type="application/ld+json">
596
- {
597
- "@context": {
598
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
599
- },
600
- "foo": [{"@value": "bar"}]
601
- }
602
- </script>
603
- <script id="second" type="application/ld+json">
604
- {
605
- "@context": {"ex": "http://example.com/"},
606
- "@graph": [
607
- {"ex:foo": {"@value": "foo"}},
608
- {"ex:bar": {"@value": "bar"}}
609
- ]
610
- }
611
- </script>
612
- </head>
613
- </html>),
614
- context: %({"ex": "http://example.com/"}),
615
- output: %({
616
- "@context": {"ex": "http://example.com/"},
617
- "@graph": [
618
- {"@id": "_:b0", "ex:foo": "foo"},
619
- {"@id": "_:b1", "ex:bar": "bar"}
620
- ]
621
- }),
622
- base: "http://example.org/doc#second"
623
- },
624
- "Flattens all script elements by default": {
625
- input: %(
626
- <html>
627
- <head>
628
- <script type="application/ld+json">
629
- {
630
- "@context": {
631
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
632
- },
633
- "foo": [{"@value": "bar"}]
634
- }
635
- </script>
636
- <script type="application/ld+json">
637
- [
638
- {"http://example.com/foo": {"@value": "foo"}},
639
- {"http://example.com/bar": {"@value": "bar"}}
640
- ]
641
- </script>
642
- </head>
643
- </html>),
644
- context: %({
645
- "ex": "http://example.com/",
646
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
647
- }),
648
- output: %({
649
- "@context": {
650
- "ex": "http://example.com/",
651
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
652
- },
653
- "@graph": [
654
- {"@id": "_:b0", "foo": ["bar"]},
655
- {"@id": "_:b1", "ex:foo": "foo"},
656
- {"@id": "_:b2", "ex:bar": "bar"}
657
- ]
658
- })
659
- },
660
- }.each do |title, params|
661
- it(title) do
662
- params[:input] = StringIO.new(params[:input])
663
- params[:input].send(:define_singleton_method, :content_type) {"text/html"}
664
- run_flatten params.merge(validate: true)
665
- end
666
- end
667
- end
668
-
669
- context "JSON-LD-star" do
670
- {
671
- "node object with @annotation property is ignored without rdfstar option": {
672
- input: %({
673
- "@id": "ex:bob",
674
- "ex:knows": {
675
- "@id": "ex:fred",
676
- "@annotation": {
677
- "ex:certainty": 0.8
678
- }
679
- }
680
- }),
681
- output: %([{
682
- "@id": "ex:bob",
683
- "ex:knows": [{"@id": "ex:fred"}]
684
- }])
685
- },
686
- "value object with @annotation property is ignored without rdfstar option": {
687
- input: %({
688
- "@id": "ex:bob",
689
- "ex:age": {
690
- "@value": 23,
691
- "@annotation": {
692
- "ex:certainty": 0.8
693
- }
694
- }
695
- }),
696
- output: %([{
697
- "@id": "ex:bob",
698
- "ex:age": [{"@value": 23}]
699
- }])
700
- },
701
- }.each do |title, params|
702
- it(title) {run_flatten params}
703
- end
704
-
705
- {
706
- "node with embedded subject having no @id": {
707
- input: %({
708
- "@id": {
709
- "ex:prop": "value"
710
- },
711
- "ex:prop": "value2"
712
- }),
713
- output: %([{
714
- "@id": {
715
- "ex:prop": [{"@value": "value"}]
716
- },
717
- "ex:prop": [{"@value": "value2"}]
718
- }])
719
- },
720
- "node with embedded subject having IRI @id": {
721
- input: %({
722
- "@id": {
723
- "@id": "ex:rei",
724
- "ex:prop": "value"
725
- },
726
- "ex:prop": "value2"
727
- }),
728
- output: %([{
729
- "@id": {
730
- "@id": "ex:rei",
731
- "ex:prop": [{"@value": "value"}]
732
- },
733
- "ex:prop": [{"@value": "value2"}]
734
- }])
735
- },
736
- "node with embedded subject having BNode @id": {
737
- input: %({
738
- "@id": {
739
- "@id": "_:rei",
740
- "ex:prop": "value"
741
- },
742
- "ex:prop": "value2"
743
- }),
744
- output: %([{
745
- "@id": {
746
- "@id": "_:b0",
747
- "ex:prop": [{"@value": "value"}]
748
- },
749
- "ex:prop": [{"@value": "value2"}]
750
- }])
751
- },
752
- "node with embedded subject having a type": {
753
- input: %({
754
- "@id": {
755
- "@id": "ex:rei",
756
- "@type": "ex:Type"
757
- },
758
- "ex:prop": "value2"
759
- }),
760
- output: %([{
761
- "@id": {
762
- "@id": "ex:rei",
763
- "@type": ["ex:Type"]
764
- },
765
- "ex:prop": [{"@value": "value2"}]
766
- }])
767
- },
768
- "node with embedded subject having an IRI value": {
769
- input: %({
770
- "@id": {
771
- "@id": "ex:rei",
772
- "ex:prop": {"@id": "ex:value"}
773
- },
774
- "ex:prop": "value2"
775
- }),
776
- output: %([{
777
- "@id": {
778
- "@id": "ex:rei",
779
- "ex:prop": [{"@id": "ex:value"}]
780
- },
781
- "ex:prop": [{"@value": "value2"}]
782
- }])
783
- },
784
- "node with embedded subject having an BNode value": {
785
- input: %({
786
- "@id": {
787
- "@id": "ex:rei",
788
- "ex:prop": {"@id": "_:value"}
789
- },
790
- "ex:prop": "value2"
791
- }),
792
- output: %([{
793
- "@id": {
794
- "@id": "ex:rei",
795
- "ex:prop": [{"@id": "_:b0"}]
796
- },
797
- "ex:prop": [{"@value": "value2"}]
798
- }])
799
- },
800
- "node with recursive embedded subject": {
801
- input: %({
802
- "@id": {
803
- "@id": {
804
- "@id": "ex:rei",
805
- "ex:prop": "value3"
806
- },
807
- "ex:prop": "value"
808
- },
809
- "ex:prop": "value2"
810
- }),
811
- output: %([{
812
- "@id": {
813
- "@id": {
814
- "@id": "ex:rei",
815
- "ex:prop": [{"@value": "value3"}]
816
- },
817
- "ex:prop": [{"@value": "value"}]
818
- },
819
- "ex:prop": [{"@value": "value2"}]
820
- }])
821
- },
822
- "node with embedded object": {
823
- input: %({
824
- "@id": "ex:subj",
825
- "ex:value": {
826
- "@id": {
827
- "@id": "ex:rei",
828
- "ex:prop": "value"
829
- }
830
- }
831
- }),
832
- output: %([{
833
- "@id": "ex:subj",
834
- "ex:value": [{
835
- "@id": {
836
- "@id": "ex:rei",
837
- "ex:prop": [{"@value": "value"}]
838
- }
839
- }]
840
- }])
841
- },
842
- "node with embedded object having properties": {
843
- input: %({
844
- "@id": "ex:subj",
845
- "ex:value": {
846
- "@id": {
847
- "@id": "ex:rei",
848
- "ex:prop": "value"
849
- },
850
- "ex:prop": "value2"
851
- }
852
- }),
853
- output: %([{
854
- "@id": "ex:subj",
855
- "ex:value": [{
856
- "@id": {
857
- "@id": "ex:rei",
858
- "ex:prop": [{"@value": "value"}]
859
- }
860
- }]
861
- }, {
862
- "@id": {
863
- "@id": "ex:rei",
864
- "ex:prop": [{"@value": "value"}]
865
- },
866
- "ex:prop": [{"@value": "value2"}]
867
- }])
868
- },
869
- "node with recursive embedded object": {
870
- input: %({
871
- "@id": "ex:subj",
872
- "ex:value": {
873
- "@id": {
874
- "@id": {
875
- "@id": "ex:rei",
876
- "ex:prop": "value3"
877
- },
878
- "ex:prop": "value"
879
- },
880
- "ex:prop": "value2"
881
- }
882
- }),
883
- output: %([{
884
- "@id": "ex:subj",
885
- "ex:value": [{
886
- "@id": {
887
- "@id": {
888
- "@id": "ex:rei",
889
- "ex:prop": [{"@value": "value3"}]
890
- },
891
- "ex:prop":[{"@value": "value"}]
892
- }
893
- }]
894
- }, {
895
- "@id": {
896
- "@id": {
897
- "@id": "ex:rei",
898
- "ex:prop": [{"@value": "value3"}]
899
- },
900
- "ex:prop":[{"@value": "value"}]
901
- },
902
- "ex:prop": [{"@value": "value2"}]
903
- }])
904
- },
905
- "node with @annotation property on value object": {
906
- input: %({
907
- "@id": "ex:bob",
908
- "ex:age": {
909
- "@value": 23,
910
- "@annotation": {"ex:certainty": 0.8}
911
- }
912
- }),
913
- output: %([{
914
- "@id": "ex:bob",
915
- "ex:age": [{"@value": 23}]
916
- }, {
917
- "@id": {
918
- "@id": "ex:bob",
919
- "ex:age": [{"@value": 23}]
920
- },
921
- "ex:certainty": [{"@value": 0.8}]
922
- }])
923
- },
924
- "node with @annotation property on node object": {
925
- input: %({
926
- "@id": "ex:bob",
927
- "ex:name": "Bob",
928
- "ex:knows": {
929
- "@id": "ex:fred",
930
- "ex:name": "Fred",
931
- "@annotation": {"ex:certainty": 0.8}
932
- }
933
- }),
934
- output: %([{
935
- "@id": "ex:bob",
936
- "ex:name": [{"@value": "Bob"}],
937
- "ex:knows": [{"@id": "ex:fred"}]
938
- }, {
939
- "@id": "ex:fred",
940
- "ex:name": [{"@value": "Fred"}]
941
- }, {
942
- "@id": {
943
- "@id": "ex:bob",
944
- "ex:knows": [{"@id": "ex:fred"}]
945
- },
946
- "ex:certainty": [{"@value": 0.8}]
947
- }])
948
- },
949
- "node with @annotation property multiple values": {
950
- input: %({
951
- "@id": "ex:bob",
952
- "ex:name": "Bob",
953
- "ex:knows": {
954
- "@id": "ex:fred",
955
- "ex:name": "Fred",
956
- "@annotation": [{
957
- "ex:certainty": 0.8
958
- }, {
959
- "ex:source": {"@id": "http://example.org/"}
960
- }]
961
- }
962
- }),
963
- output: %([{
964
- "@id": "ex:bob",
965
- "ex:name": [{"@value": "Bob"}],
966
- "ex:knows": [{"@id": "ex:fred"}]
967
- }, {
968
- "@id": "ex:fred",
969
- "ex:name": [{"@value": "Fred"}]
970
- }, {
971
- "@id": {
972
- "@id": "ex:bob",
973
- "ex:knows": [{"@id": "ex:fred"}]
974
- },
975
- "ex:certainty": [{"@value": 0.8}],
976
- "ex:source": [{"@id": "http://example.org/"}]
977
- }])
978
- },
979
- "node with @annotation property on embedded subject": {
980
- input: %({
981
- "@id": {
982
- "@id": "ex:rei",
983
- "ex:prop": {"@id": "_:value"}
984
- },
985
- "ex:prop": {
986
- "@value": "value2",
987
- "@annotation": {"ex:certainty": 0.8}
988
- }
989
- }),
990
- output: %([{
991
- "@id": {
992
- "@id": "ex:rei",
993
- "ex:prop": [{"@id": "_:b0"}]
994
- },
995
- "ex:prop": [{"@value": "value2"}]
996
- }, {
997
- "@id": {
998
- "@id": {
999
- "@id": "ex:rei",
1000
- "ex:prop": [{"@id": "_:b0"}]
1001
- },
1002
- "ex:prop": [{"@value": "value2"}]
1003
- },
1004
- "ex:certainty": [{"@value": 0.8}]
1005
- }])
1006
- },
1007
- "node with @annotation property on embedded object": {
1008
- input: %({
1009
- "@id": "ex:subj",
1010
- "ex:value": {
1011
- "@id": {
1012
- "@id": "ex:rei",
1013
- "ex:prop": "value"
1014
- },
1015
- "@annotation": {"ex:certainty": 0.8}
1016
- }
1017
- }),
1018
- output: %([{
1019
- "@id": "ex:subj",
1020
- "ex:value": [{
1021
- "@id": {
1022
- "@id": "ex:rei",
1023
- "ex:prop": [{"@value": "value"}]
1024
- }
1025
- }]
1026
- }, {
1027
- "@id": {
1028
- "@id": "ex:subj",
1029
- "ex:value": [{
1030
- "@id": {
1031
- "@id": "ex:rei",
1032
- "ex:prop": [{"@value": "value"}]
1033
- }
1034
- }]
1035
- },
1036
- "ex:certainty": [{"@value": 0.8}]
1037
- }])
1038
- },
1039
- "embedded node used as subject in reverse relationship": {
1040
- input: %({
1041
- "@context": {
1042
- "rel": {"@reverse": "ex:rel"}
1043
- },
1044
- "@id": {
1045
- "@id": "ex:rei",
1046
- "ex:prop": {"@id": "ex:value"}
1047
- },
1048
- "rel": {"@id": "ex:value2"}
1049
- }),
1050
- output: %([{
1051
- "@id": "ex:value2",
1052
- "ex:rel": [{
1053
- "@id": {
1054
- "@id": "ex:rei",
1055
- "ex:prop": [{"@id": "ex:value"}]
1056
- }
1057
- }]
1058
- }])
1059
- },
1060
- "embedded node used as object in reverse relationship": {
1061
- input: %({
1062
- "@context": {
1063
- "rel": {"@reverse": "ex:rel"}
1064
- },
1065
- "@id": "ex:subj",
1066
- "rel": {
1067
- "@id": {
1068
- "@id": "ex:rei",
1069
- "ex:prop": {"@id": "ex:value"}
1070
- },
1071
- "ex:prop": {"@id": "ex:value2"}
1072
- }
1073
- }),
1074
- output: %([{
1075
- "@id": {
1076
- "@id": "ex:rei",
1077
- "ex:prop": [{"@id": "ex:value"}]
1078
- },
1079
- "ex:rel": [{"@id": "ex:subj"}],
1080
- "ex:prop": [{"@id": "ex:value2"}]
1081
- }])
1082
- },
1083
- "node with @annotation property on node object with reverse relationship": {
1084
- input: %({
1085
- "@context": {
1086
- "knownBy": {"@reverse": "ex:knows"}
1087
- },
1088
- "@id": "ex:bob",
1089
- "ex:name": "Bob",
1090
- "knownBy": {
1091
- "@id": "ex:fred",
1092
- "ex:name": "Fred",
1093
- "@annotation": {"ex:certainty": 0.8}
1094
- }
1095
- }),
1096
- output: %([{
1097
- "@id": "ex:bob",
1098
- "ex:name": [{"@value": "Bob"}]
1099
- }, {
1100
- "@id": "ex:fred",
1101
- "ex:name": [{"@value": "Fred"}],
1102
- "ex:knows": [{"@id": "ex:bob"}]
1103
- }, {
1104
- "@id": {
1105
- "@id": "ex:fred",
1106
- "ex:knows": [{"@id": "ex:bob"}]
1107
- },
1108
- "ex:certainty": [{"@value": 0.8}]
1109
- }])
1110
- },
1111
- "reverse relationship inside annotation": {
1112
- input: %({
1113
- "@context": {
1114
- "claims": {"@reverse": "ex:claims", "@type": "@id"}
1115
- },
1116
- "@id": "ex:bob",
1117
- "ex:knows": {
1118
- "@id": "ex:jane",
1119
- "@annotation": {
1120
- "ex:certainty": 0.8,
1121
- "claims": "ex:sue"
1122
- }
1123
- }
1124
- }),
1125
- output: %([{
1126
- "@id": "ex:bob",
1127
- "ex:knows": [{"@id": "ex:jane"}]
1128
- }, {
1129
- "@id": {
1130
- "@id": "ex:bob",
1131
- "ex:knows": [{"@id": "ex:jane"}]
1132
- },
1133
- "ex:certainty": [{"@value": 0.8}]
1134
- }, {
1135
- "@id": "ex:sue",
1136
- "ex:claims": [{
1137
- "@id": {
1138
- "@id": "ex:bob",
1139
- "ex:knows": [{"@id": "ex:jane"}]
1140
- }
1141
- }]
1142
- }])
1143
- },
1144
- "embedded node with annotation on value object": {
1145
- input: %({
1146
- "@context": {
1147
- "@base": "http://example.org/",
1148
- "@vocab": "http://example.org/",
1149
- "claims": {"@type": "@id"}
1150
- },
1151
- "@id": {
1152
- "@id": "bob",
1153
- "knows": {"@id": "alice"}
1154
- },
1155
- "certainty": {
1156
- "@value": 0.8,
1157
- "@annotation": {"claims": "ted"}
1158
- }
1159
- }),
1160
- output: %([{
1161
- "@id": {
1162
- "@id": "http://example.org/bob",
1163
- "http://example.org/knows": [{"@id": "http://example.org/alice"}]
1164
- },
1165
- "http://example.org/certainty": [{"@value": 0.8}]
1166
- }, {
1167
- "@id": {
1168
- "@id": {
1169
- "@id": "http://example.org/bob",
1170
- "http://example.org/knows": [{"@id": "http://example.org/alice"}]
1171
- },
1172
- "http://example.org/certainty": [{"@value": 0.8}]
1173
- },
1174
- "http://example.org/claims": [{"@id": "http://example.org/ted"}]
1175
- }])
1176
- }
1177
- }.each do |title, params|
1178
- it(title) {run_flatten params.merge(rdfstar: true)}
1179
- end
1180
- end
1181
-
1182
- def run_flatten(params)
1183
- input, output, context = params[:input], params[:output], params[:context]
1184
- input = ::JSON.parse(input) if input.is_a?(String)
1185
- output = ::JSON.parse(output) if output.is_a?(String)
1186
- context = ::JSON.parse(context) if context.is_a?(String)
1187
- params[:base] ||= nil
1188
- pending params.fetch(:pending, "test implementation") unless input
1189
- if params[:exception]
1190
- expect {JSON::LD::API.flatten(input, context, logger: logger, **params)}.to raise_error(params[:exception])
1191
- else
1192
- jld = nil
1193
- if params[:write]
1194
- expect{jld = JSON::LD::API.flatten(input, context, logger: logger, **params)}.to write(params[:write]).to(:error)
1195
- else
1196
- expect{jld = JSON::LD::API.flatten(input, context, logger: logger, **params)}.not_to write.to(:error)
1197
- end
1198
-
1199
- jld = remap_bnodes(jld, output) if params[:remap_nodes]
1200
- expect(jld).to produce_jsonld(output, logger)
1201
- end
1202
- end
1203
- end