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/to_rdf_spec.rb DELETED
@@ -1,1684 +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
- context ".toRdf" do
8
- it "should implement RDF::Enumerable" do
9
- expect(JSON::LD::API.toRdf({})).to be_a(RDF::Enumerable)
10
- end
11
-
12
- context "unnamed nodes" do
13
- {
14
- "no @id" => [
15
- %q({
16
- "http://example.com/foo": "bar"
17
- }),
18
- %q([ <http://example.com/foo> "bar"^^xsd:string] .)
19
- ],
20
- "@id with _:a" => [
21
- %q({
22
- "@id": "_:a",
23
- "http://example.com/foo": "bar"
24
- }),
25
- %q([ <http://example.com/foo> "bar"^^xsd:string] .)
26
- ],
27
- "@id with _:a and reference" => [
28
- %q({
29
- "@id": "_:a",
30
- "http://example.com/foo": {"@id": "_:a"}
31
- }),
32
- %q(_:a <http://example.com/foo> _:a .)
33
- ],
34
- }.each do |title, (js, ttl)|
35
- it title do
36
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
37
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
38
- end
39
- end
40
- end
41
-
42
- context "nodes with @id" do
43
- {
44
- "with IRI" => [
45
- %q({
46
- "@id": "http://example.com/a",
47
- "http://example.com/foo": "bar"
48
- }),
49
- %q(<http://example.com/a> <http://example.com/foo> "bar" .)
50
- ],
51
- }.each do |title, (js, ttl)|
52
- it title do
53
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
54
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
55
- end
56
- end
57
-
58
- context "with relative IRIs" do
59
- {
60
- "base" => [
61
- %({
62
- "@id": "",
63
- "@type": "#{RDF::RDFS.Resource}"
64
- }),
65
- %(<http://example.org/> a <#{RDF::RDFS.Resource}> .)
66
- ],
67
- "relative" => [
68
- %({
69
- "@id": "a/b",
70
- "@type": "#{RDF::RDFS.Resource}"
71
- }),
72
- %(<http://example.org/a/b> a <#{RDF::RDFS.Resource}> .)
73
- ],
74
- "hash" => [
75
- %({
76
- "@id": "#a",
77
- "@type": "#{RDF::RDFS.Resource}"
78
- }),
79
- %(<http://example.org/#a> a <#{RDF::RDFS.Resource}> .)
80
- ],
81
- }.each do |title, (js, ttl)|
82
- it title do
83
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
84
- expect(parse(js, base: "http://example.org/")).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
85
- end
86
- end
87
- end
88
- end
89
-
90
- context "typed nodes" do
91
- {
92
- "one type" => [
93
- %q({
94
- "@type": "http://example.com/foo"
95
- }),
96
- %q([ a <http://example.com/foo> ] .)
97
- ],
98
- "two types" => [
99
- %q({
100
- "@type": ["http://example.com/foo", "http://example.com/baz"]
101
- }),
102
- %q([ a <http://example.com/foo>, <http://example.com/baz> ] .)
103
- ],
104
- "blank node type" => [
105
- %q({
106
- "@type": "_:foo"
107
- }),
108
- %q([ a _:foo ] .)
109
- ]
110
- }.each do |title, (js, ttl)|
111
- it title do
112
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
113
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
114
- end
115
- end
116
- end
117
-
118
- context "key/value" do
119
- {
120
- "string" => [
121
- %q({
122
- "http://example.com/foo": "bar"
123
- }),
124
- %q([ <http://example.com/foo> "bar"^^xsd:string ] .)
125
- ],
126
- "strings" => [
127
- %q({
128
- "http://example.com/foo": ["bar", "baz"]
129
- }),
130
- %q([ <http://example.com/foo> "bar"^^xsd:string, "baz"^^xsd:string ] .)
131
- ],
132
- "IRI" => [
133
- %q({
134
- "http://example.com/foo": {"@id": "http://example.com/bar"}
135
- }),
136
- %q([ <http://example.com/foo> <http://example.com/bar> ] .)
137
- ],
138
- "IRIs" => [
139
- %q({
140
- "http://example.com/foo": [{"@id": "http://example.com/bar"}, {"@id": "http://example.com/baz"}]
141
- }),
142
- %q([ <http://example.com/foo> <http://example.com/bar>, <http://example.com/baz> ] .)
143
- ],
144
- }.each do |title, (js, ttl)|
145
- it title do
146
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
147
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
148
- end
149
- end
150
- end
151
-
152
- context "literals" do
153
- {
154
- "plain literal" =>
155
- [
156
- %q({"@id": "http://greggkellogg.net/foaf#me", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg"}),
157
- %q(<http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/name> "Gregg Kellogg" .)
158
- ],
159
- "explicit plain literal" =>
160
- [
161
- %q({"http://xmlns.com/foaf/0.1/name": {"@value": "Gregg Kellogg"}}),
162
- %q(_:a <http://xmlns.com/foaf/0.1/name> "Gregg Kellogg"^^xsd:string .)
163
- ],
164
- "language tagged literal" =>
165
- [
166
- %q({"http://www.w3.org/2000/01/rdf-schema#label": {"@value": "A plain literal with a lang tag.", "@language": "en-us"}}),
167
- %q(_:a <http://www.w3.org/2000/01/rdf-schema#label> "A plain literal with a lang tag."@en-us .)
168
- ],
169
- "I18N literal with language" =>
170
- [
171
- %q([{
172
- "@id": "http://greggkellogg.net/foaf#me",
173
- "http://xmlns.com/foaf/0.1/knows": {"@id": "http://www.ivan-herman.net/foaf#me"}
174
- },{
175
- "@id": "http://www.ivan-herman.net/foaf#me",
176
- "http://xmlns.com/foaf/0.1/name": {"@value": "Herman Iván", "@language": "hu"}
177
- }]),
178
- %q(
179
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.ivan-herman.net/foaf#me> .
180
- <http://www.ivan-herman.net/foaf#me> <http://xmlns.com/foaf/0.1/name> "Herman Iv\u00E1n"@hu .
181
- )
182
- ],
183
- "explicit datatyped literal" =>
184
- [
185
- %q({
186
- "@id": "http://greggkellogg.net/foaf#me",
187
- "http://purl.org/dc/terms/created": {"@value": "1957-02-27", "@type": "http://www.w3.org/2001/XMLSchema#date"}
188
- }),
189
- %q(
190
- <http://greggkellogg.net/foaf#me> <http://purl.org/dc/terms/created> "1957-02-27"^^<http://www.w3.org/2001/XMLSchema#date> .
191
- )
192
- ],
193
- }.each do |title, (js, ttl)|
194
- it title do
195
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
196
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
197
- end
198
- end
199
-
200
- context "with @type: @json" do
201
- {
202
- "true": {
203
- input: %({
204
- "@context": {
205
- "@version": 1.1,
206
- "e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
207
- },
208
- "e": true
209
- }),
210
- output:%(
211
- @prefix ex: <http://example.org/vocab#> .
212
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
213
- [ex:bool "true"^^rdf:JSON] .
214
- )
215
- },
216
- "false": {
217
- input: %({
218
- "@context": {
219
- "@version": 1.1,
220
- "e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
221
- },
222
- "e": false
223
- }),
224
- output: %(
225
- @prefix ex: <http://example.org/vocab#> .
226
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
227
- [ex:bool "false"^^rdf:JSON] .
228
- )
229
- },
230
- "double": {
231
- input: %({
232
- "@context": {
233
- "@version": 1.1,
234
- "e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
235
- },
236
- "e": 1.23
237
- }),
238
- output: %(
239
- @prefix ex: <http://example.org/vocab#> .
240
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
241
- [ex:double "1.23"^^rdf:JSON] .
242
- )
243
- },
244
- "double-zero": {
245
- input: %({
246
- "@context": {
247
- "@version": 1.1,
248
- "e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
249
- },
250
- "e": 0
251
- }),
252
- output: %(
253
- @prefix ex: <http://example.org/vocab#> .
254
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
255
- [ex:double "0"^^rdf:JSON] .
256
- )
257
- },
258
- "integer": {
259
- input: %({
260
- "@context": {
261
- "@version": 1.1,
262
- "e": {"@id": "http://example.org/vocab#integer", "@type": "@json"}
263
- },
264
- "e": 123
265
- }),
266
- output: %(
267
- @prefix ex: <http://example.org/vocab#> .
268
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
269
- [ex:integer "123"^^rdf:JSON] .
270
- )
271
- },
272
- "string": {
273
- input: %({
274
- "@context": {
275
- "@version": 1.1,
276
- "e": {"@id": "http://example.org/vocab#string", "@type": "@json"}
277
- },
278
- "e": "string"
279
- }),
280
- output: %(
281
- @prefix ex: <http://example.org/vocab#> .
282
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
283
- [ex:string "\\"string\\""^^rdf:JSON] .
284
- )
285
- },
286
- "null": {
287
- input: %({
288
- "@context": {
289
- "@version": 1.1,
290
- "e": {"@id": "http://example.org/vocab#null", "@type": "@json"}
291
- },
292
- "e": null
293
- }),
294
- output: %(
295
- @prefix ex: <http://example.org/vocab#> .
296
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
297
- [ex:null "null"^^rdf:JSON] .
298
- )
299
- },
300
- "object": {
301
- input: %({
302
- "@context": {
303
- "@version": 1.1,
304
- "e": {"@id": "http://example.org/vocab#object", "@type": "@json"}
305
- },
306
- "e": {"foo": "bar"}
307
- }),
308
- output: %(
309
- @prefix ex: <http://example.org/vocab#> .
310
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
311
- [ex:object """{"foo":"bar"}"""^^rdf:JSON] .
312
- )
313
- },
314
- "array": {
315
- input: %({
316
- "@context": {
317
- "@version": 1.1,
318
- "e": {"@id": "http://example.org/vocab#array", "@type": "@json"}
319
- },
320
- "e": [{"foo": "bar"}]
321
- }),
322
- output: %(
323
- @prefix ex: <http://example.org/vocab#> .
324
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
325
- [ex:array """[{"foo":"bar"}]"""^^rdf:JSON] .
326
- )
327
- },
328
- "c14n-arrays": {
329
- input: %({
330
- "@context": {
331
- "@version": 1.1,
332
- "e": {"@id": "http://example.org/vocab#c14n", "@type": "@json"}
333
- },
334
- "e": [
335
- 56,
336
- {
337
- "d": true,
338
- "10": null,
339
- "1": [ ]
340
- }
341
- ]
342
- }),
343
- output: %(
344
- @prefix ex: <http://example.org/vocab#> .
345
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
346
- [ex:c14n """[56,{"1":[],"10":null,"d":true}]"""^^rdf:JSON] .
347
- )
348
- },
349
- "c14n-french": {
350
- input: %({
351
- "@context": {
352
- "@version": 1.1,
353
- "e": {"@id": "http://example.org/vocab#c14n", "@type": "@json"}
354
- },
355
- "e": {
356
- "peach": "This sorting order",
357
- "péché": "is wrong according to French",
358
- "pêche": "but canonicalization MUST",
359
- "sin": "ignore locale"
360
- }
361
- }),
362
- output: %(
363
- @prefix ex: <http://example.org/vocab#> .
364
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
365
- [ex:c14n """{"peach":"This sorting order","péché":"is wrong according to French","pêche":"but canonicalization MUST","sin":"ignore locale"}"""^^rdf:JSON] .
366
- )
367
- },
368
- "c14n-structures": {
369
- input: %({
370
- "@context": {
371
- "@version": 1.1,
372
- "e": {"@id": "http://example.org/vocab#c14n", "@type": "@json"}
373
- },
374
- "e": {
375
- "1": {"f": {"f": "hi","F": 5} ," ": 56.0},
376
- "10": { },
377
- "": "empty",
378
- "a": { },
379
- "111": [ {"e": "yes","E": "no" } ],
380
- "A": { }
381
- }
382
- }),
383
- output: %(
384
- @prefix ex: <http://example.org/vocab#> .
385
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
386
- [ex:c14n """{"":"empty","1":{" ":56,"f":{"F":5,"f":"hi"}},"10":{},"111":[{"E":"no","e":"yes"}],"A":{},"a":{}}"""^^rdf:JSON] .
387
- )
388
- },
389
- "c14n-unicode": {
390
- input: %({
391
- "@context": {
392
- "@version": 1.1,
393
- "e": {"@id": "http://example.org/vocab#c14n", "@type": "@json"}
394
- },
395
- "e": {
396
- "Unnormalized Unicode":"A\u030a"
397
- }
398
- }),
399
- output: %(
400
- @prefix ex: <http://example.org/vocab#> .
401
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
402
- [ex:c14n """{"Unnormalized Unicode":"Å"}"""^^rdf:JSON] .
403
- )
404
- },
405
- }.each do |title, params|
406
- it title do
407
- params[:output] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:output])
408
- run_to_rdf params
409
- end
410
- end
411
- end
412
-
413
- context "with xsd: true" do
414
- {
415
- "true": {
416
- input: {
417
- "@context" => {
418
- "e" => "http://example.org/vocab#e"
419
- },
420
- "e" => RDF::Literal(true)
421
- },
422
- output: %(
423
- @prefix ex: <http://example.org/vocab#> .
424
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
425
- [ex:e true] .
426
- )
427
- },
428
- "integer": {
429
- input: {
430
- "@context" => {
431
- "e" => "http://example.org/vocab#e"
432
- },
433
- "e" => RDF::Literal(1)
434
- },
435
- output: %(
436
- @prefix ex: <http://example.org/vocab#> .
437
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
438
- [ex:e 1] .
439
- )
440
- },
441
- "decimal": {
442
- input: {
443
- "@context" => {
444
- "e" => "http://example.org/vocab#e"
445
- },
446
- "e" => RDF::Literal::Decimal.new("1.1")
447
- },
448
- output: %(
449
- @prefix ex: <http://example.org/vocab#> .
450
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
451
- [ex:e 1.1] .
452
- )
453
- },
454
- "float": {
455
- input: {
456
- "@context" => {
457
- "e" => "http://example.org/vocab#e"
458
- },
459
- "e" => RDF::Literal.new("1.1e1", datatype: RDF::XSD.float)
460
- },
461
- output: %(
462
- @prefix ex: <http://example.org/vocab#> .
463
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
464
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
465
- [ex:e "1.1e1"^^xsd:float] .
466
- )
467
- },
468
- "double": {
469
- input: {
470
- "@context" => {
471
- "e" => "http://example.org/vocab#e"
472
- },
473
- "e" => RDF::Literal.new("1.1e1", datatype: RDF::XSD.double)
474
- },
475
- output: %(
476
- @prefix ex: <http://example.org/vocab#> .
477
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
478
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
479
- [ex:e 1.1e1] .
480
- )
481
- },
482
- "date": {
483
- input: {
484
- "@context" => {
485
- "e" => "http://example.org/vocab#e"
486
- },
487
- "e" => RDF::Literal.new("2022-08-27", datatype: RDF::XSD.date)
488
- },
489
- output: %(
490
- @prefix ex: <http://example.org/vocab#> .
491
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
492
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
493
- [ex:e "2022-08-27"^^xsd:date] .
494
- )
495
- },
496
- "time": {
497
- input: {
498
- "@context" => {
499
- "e" => "http://example.org/vocab#e"
500
- },
501
- "e" => RDF::Literal.new("12:00:00", datatype: RDF::XSD.time)
502
- },
503
- output: %(
504
- @prefix ex: <http://example.org/vocab#> .
505
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
506
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
507
- [ex:e "12:00:00"^^xsd:time] .
508
- )
509
- },
510
- "dateTime": {
511
- input: {
512
- "@context" => {
513
- "e" => "http://example.org/vocab#e"
514
- },
515
- "e" => RDF::Literal.new("2022-08-27T12:00:00", datatype: RDF::XSD.dateTime)
516
- },
517
- output: %(
518
- @prefix ex: <http://example.org/vocab#> .
519
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
520
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
521
- [ex:e "2022-08-27T12:00:00"^^xsd:dateTime] .
522
- )
523
- },
524
- "language": {
525
- input: {
526
- "@context" => {
527
- "e" => "http://example.org/vocab#e"
528
- },
529
- "e" => RDF::Literal.new("language", language: :"en-us")
530
- },
531
- output: %(
532
- @prefix ex: <http://example.org/vocab#> .
533
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
534
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
535
- [ex:e "language"@en-us] .
536
- )
537
- },
538
- }.each do |title, params|
539
- it title do
540
- params[:output] = RDF::Graph.new << RDF::Turtle::Reader.new(params[:output])
541
- run_to_rdf(params.merge(xsd: true))
542
- end
543
- end
544
- end
545
- end
546
-
547
- context "prefixes" do
548
- {
549
- "empty suffix" => [
550
- %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:": "bar"}),
551
- %q(_:a <http://example.com/default#> "bar"^^xsd:string .)
552
- ],
553
- "prefix:suffix" => [
554
- %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:foo": "bar"}),
555
- %q(_:a <http://example.com/default#foo> "bar"^^xsd:string .)
556
- ]
557
- }.each_pair do |title, (js, ttl)|
558
- it title do
559
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
560
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
561
- end
562
- end
563
- end
564
-
565
- context "overriding keywords" do
566
- {
567
- "'url' for @id, 'a' for @type" => [
568
- %q({
569
- "@context": {"url": "@id", "a": "@type", "name": "http://schema.org/name"},
570
- "url": "http://example.com/about#gregg",
571
- "a": "http://schema.org/Person",
572
- "name": "Gregg Kellogg"
573
- }),
574
- %q(
575
- <http://example.com/about#gregg> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> .
576
- <http://example.com/about#gregg> <http://schema.org/name> "Gregg Kellogg"^^xsd:string .
577
- )
578
- ],
579
- }.each do |title, (js, ttl)|
580
- it title do
581
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
582
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
583
- end
584
- end
585
- end
586
-
587
- context "chaining" do
588
- {
589
- "explicit subject" =>
590
- [
591
- %q({
592
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
593
- "@id": "http://greggkellogg.net/foaf#me",
594
- "foaf:knows": {
595
- "@id": "http://www.ivan-herman.net/foaf#me",
596
- "foaf:name": "Ivan Herman"
597
- }
598
- }),
599
- %q(
600
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.ivan-herman.net/foaf#me> .
601
- <http://www.ivan-herman.net/foaf#me> <http://xmlns.com/foaf/0.1/name> "Ivan Herman" .
602
- )
603
- ],
604
- "implicit subject" =>
605
- [
606
- %q({
607
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
608
- "@id": "http://greggkellogg.net/foaf#me",
609
- "foaf:knows": {
610
- "foaf:name": "Manu Sporny"
611
- }
612
- }),
613
- %q(
614
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
615
- _:a <http://xmlns.com/foaf/0.1/name> "Manu Sporny"^^xsd:string .
616
- )
617
- ],
618
- }.each do |title, (js, ttl)|
619
- it title do
620
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
621
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
622
- end
623
- end
624
- end
625
-
626
- context "multiple values" do
627
- {
628
- "literals" =>
629
- [
630
- %q({
631
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
632
- "@id": "http://greggkellogg.net/foaf#me",
633
- "foaf:knows": ["Manu Sporny", "Ivan Herman"]
634
- }),
635
- %q(
636
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> "Manu Sporny" .
637
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> "Ivan Herman" .
638
- )
639
- ],
640
- }.each do |title, (js, ttl)|
641
- it title do
642
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
643
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
644
- end
645
- end
646
- end
647
-
648
- context "lists" do
649
- {
650
- "Empty" => [
651
- %q({
652
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
653
- "@id": "http://greggkellogg.net/foaf#me",
654
- "foaf:knows": {"@list": []}
655
- }),
656
- %q(
657
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
658
- )
659
- ],
660
- "single value" => [
661
- %q({
662
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
663
- "@id": "http://greggkellogg.net/foaf#me",
664
- "foaf:knows": {"@list": ["Manu Sporny"]}
665
- }),
666
- %q(
667
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
668
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
669
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
670
- )
671
- ],
672
- "single value (with coercion)" => [
673
- %q({
674
- "@context": {
675
- "foaf": "http://xmlns.com/foaf/0.1/",
676
- "foaf:knows": { "@container": "@list"}
677
- },
678
- "@id": "http://greggkellogg.net/foaf#me",
679
- "foaf:knows": ["Manu Sporny"]
680
- }),
681
- %q(
682
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
683
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
684
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
685
- )
686
- ],
687
- "multiple values" => [
688
- %q({
689
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
690
- "@id": "http://greggkellogg.net/foaf#me",
691
- "foaf:knows": {"@list": ["Manu Sporny", "Dave Longley"]}
692
- }),
693
- %q(
694
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
695
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
696
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b .
697
- _:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Dave Longley"^^xsd:string .
698
- _:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
699
- )
700
- ],
701
- "@list containing @list" => [
702
- %q({
703
- "@id": "http://example/A",
704
- "http://example.com/foo": {"@list": [{"@list": ["baz"]}]}
705
- }),
706
- %q(
707
- <http://example/A> <http://example.com/foo> (("baz")) .
708
- )
709
- ],
710
- "@list containing empty @list" => [
711
- %({
712
- "@id": "http://example/A",
713
- "http://example.com/foo": {"@list": [{"@list": []}]}
714
- }),
715
- %q(
716
- <http://example/A> <http://example.com/foo> (()) .
717
- )
718
- ],
719
- }.each do |title, (js, ttl)|
720
- it title do
721
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
722
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
723
- end
724
- end
725
- end
726
-
727
- context "context" do
728
- {
729
- "@id coersion" =>
730
- [
731
- %q({
732
- "@context": {
733
- "knows": {"@id": "http://xmlns.com/foaf/0.1/knows", "@type": "@id"}
734
- },
735
- "@id": "http://greggkellogg.net/foaf#me",
736
- "knows": "http://www.ivan-herman.net/foaf#me"
737
- }),
738
- %q(
739
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.ivan-herman.net/foaf#me> .
740
- )
741
- ],
742
- "datatype coersion" =>
743
- [
744
- %q({
745
- "@context": {
746
- "dcterms": "http://purl.org/dc/terms/",
747
- "xsd": "http://www.w3.org/2001/XMLSchema#",
748
- "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:date"}
749
- },
750
- "@id": "http://greggkellogg.net/foaf#me",
751
- "created": "1957-02-27"
752
- }),
753
- %q(
754
- <http://greggkellogg.net/foaf#me> <http://purl.org/dc/terms/created> "1957-02-27"^^<http://www.w3.org/2001/XMLSchema#date> .
755
- )
756
- ],
757
- "sub-objects with context" => [
758
- %q({
759
- "@context": {"foo": "http://example.com/foo"},
760
- "foo": {
761
- "@context": {"foo": "http://example.org/foo"},
762
- "foo": "bar"
763
- }
764
- }),
765
- %q(
766
- _:a <http://example.com/foo> _:b .
767
- _:b <http://example.org/foo> "bar"^^xsd:string .
768
- )
769
- ],
770
- "contexts with a list processed in order" => [
771
- %q({
772
- "@context": [
773
- {"foo": "http://example.com/foo"},
774
- {"foo": "http://example.org/foo"}
775
- ],
776
- "foo": "bar"
777
- }),
778
- %q(
779
- _:b <http://example.org/foo> "bar"^^xsd:string .
780
- )
781
- ],
782
- "term definition resolves term as IRI" => [
783
- %q({
784
- "@context": [
785
- {"foo": "http://example.com/foo"},
786
- {"bar": "foo"}
787
- ],
788
- "bar": "bar"
789
- }),
790
- %q(
791
- _:b <http://example.com/foo> "bar"^^xsd:string .
792
- )
793
- ],
794
- "term definition resolves prefix as IRI" => [
795
- %q({
796
- "@context": [
797
- {"foo": "http://example.com/foo#"},
798
- {"bar": "foo:bar"}
799
- ],
800
- "bar": "bar"
801
- }),
802
- %q(
803
- _:b <http://example.com/foo#bar> "bar"^^xsd:string .
804
- )
805
- ],
806
- "@language" => [
807
- %q({
808
- "@context": {
809
- "foo": "http://example.com/foo#",
810
- "@language": "en"
811
- },
812
- "foo:bar": "baz"
813
- }),
814
- %q(
815
- _:a <http://example.com/foo#bar> "baz"@en .
816
- )
817
- ],
818
- "@language with override" => [
819
- %q({
820
- "@context": {
821
- "foo": "http://example.com/foo#",
822
- "@language": "en"
823
- },
824
- "foo:bar": {"@value": "baz", "@language": "fr"}
825
- }),
826
- %q(
827
- _:a <http://example.com/foo#bar> "baz"@fr .
828
- )
829
- ],
830
- "@language with plain" => [
831
- %q({
832
- "@context": {
833
- "foo": "http://example.com/foo#",
834
- "@language": "en"
835
- },
836
- "foo:bar": {"@value": "baz"}
837
- }),
838
- %q(
839
- _:a <http://example.com/foo#bar> "baz"^^xsd:string .
840
- )
841
- ],
842
- }.each do |title, (js, ttl)|
843
- it title do
844
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
845
- expect(parse(js)).to be_equivalent_graph(ttl, base: "http://example/", logger: logger, inputDocument: js)
846
- end
847
- end
848
-
849
- context "coercion" do
850
- context "term def with @id + @type" do
851
- {
852
- "dt with term" => [
853
- %q({
854
- "@context": [
855
- {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"},
856
- {"foo": {"@id": "term", "@type": "date"}}
857
- ],
858
- "foo": "bar"
859
- }),
860
- %q(
861
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
862
- [ <http://example.org/foo#> "bar"^^xsd:date ] .
863
- )
864
- ],
865
- "@id with term" => [
866
- %q({
867
- "@context": [
868
- {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id"}}
869
- ],
870
- "foo": "http://example.org/foo#bar"
871
- }),
872
- %q(
873
- _:a <http://example.org/foo#bar> <http://example.org/foo#bar> .
874
- )
875
- ],
876
- "coercion without term definition" => [
877
- %q({
878
- "@context": [
879
- {
880
- "xsd": "http://www.w3.org/2001/XMLSchema#",
881
- "dc": "http://purl.org/dc/terms/"
882
- },
883
- {
884
- "dc:date": {"@type": "xsd:date"}
885
- }
886
- ],
887
- "dc:date": "2011-11-23"
888
- }),
889
- %q(
890
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
891
- @prefix dc: <http://purl.org/dc/terms/> .
892
- [ dc:date "2011-11-23"^^xsd:date] .
893
- )
894
- ],
895
- }.each do |title, (js, ttl)|
896
- it title do
897
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
898
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
899
- end
900
- end
901
- end
902
- end
903
-
904
- context "lists" do
905
- context "term def with @id + @type + @container" do
906
- {
907
- "dt with term" => [
908
- %q({
909
- "@context": [
910
- {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"},
911
- {"foo": {"@id": "term", "@type": "date", "@container": "@list"}}
912
- ],
913
- "foo": ["bar"]
914
- }),
915
- %q(
916
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
917
- [ <http://example.org/foo#> ("bar"^^xsd:date) ] .
918
- )
919
- ],
920
- "@id with term" => [
921
- %q({
922
- "@context": [
923
- {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id", "@container": "@list"}}
924
- ],
925
- "foo": ["http://example.org/foo#bar"]
926
- }),
927
- %q(
928
- _:a <http://example.org/foo#bar> (<http://example.org/foo#bar>) .
929
- )
930
- ],
931
- }.each do |title, (js, ttl)|
932
- it title do
933
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
934
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
935
- end
936
- end
937
- end
938
- end
939
- end
940
-
941
- context "blank node predicates" do
942
- subject {%q({"@id": "http://example/subj", "_:foo": "bar"})}
943
-
944
- it "outputs statements with blank node predicates if :produceGeneralizedRdf is true" do
945
- expect do
946
- graph = parse(subject, produceGeneralizedRdf: true)
947
- expect(graph.count).to eq 1
948
- end.to write("[DEPRECATION]").to(:error)
949
- end
950
-
951
- it "rejects statements with blank node predicates if :produceGeneralizedRdf is false" do
952
- expect do
953
- graph = parse(subject, produceGeneralizedRdf: false)
954
- expect(graph.count).to eq 0
955
- end.to write("[DEPRECATION]").to(:error)
956
- end
957
- end
958
-
959
- context "@included" do
960
- {
961
- "Basic Included array": {
962
- input: %({
963
- "@context": {
964
- "@version": 1.1,
965
- "@vocab": "http://example.org/"
966
- },
967
- "prop": "value",
968
- "@included": [{
969
- "prop": "value2"
970
- }]
971
- }),
972
- output: %(
973
- [<http://example.org/prop> "value"] .
974
- [<http://example.org/prop> "value2"] .
975
- )
976
- },
977
- "Basic Included object": {
978
- input: %({
979
- "@context": {
980
- "@version": 1.1,
981
- "@vocab": "http://example.org/"
982
- },
983
- "prop": "value",
984
- "@included": {
985
- "prop": "value2"
986
- }
987
- }),
988
- output: %(
989
- [<http://example.org/prop> "value"] .
990
- [<http://example.org/prop> "value2"] .
991
- )
992
- },
993
- "Multiple properties mapping to @included are folded together": {
994
- input: %({
995
- "@context": {
996
- "@version": 1.1,
997
- "@vocab": "http://example.org/",
998
- "included1": "@included",
999
- "included2": "@included"
1000
- },
1001
- "included1": {"prop": "value1"},
1002
- "included2": {"prop": "value2"}
1003
- }),
1004
- output: %(
1005
- [<http://example.org/prop> "value1"] .
1006
- [<http://example.org/prop> "value2"] .
1007
- )
1008
- },
1009
- "Included containing @included": {
1010
- input: %({
1011
- "@context": {
1012
- "@version": 1.1,
1013
- "@vocab": "http://example.org/"
1014
- },
1015
- "prop": "value",
1016
- "@included": {
1017
- "prop": "value2",
1018
- "@included": {
1019
- "prop": "value3"
1020
- }
1021
- }
1022
- }),
1023
- output: %(
1024
- [<http://example.org/prop> "value"] .
1025
-
1026
- [<http://example.org/prop> "value2"] .
1027
-
1028
- [<http://example.org/prop> "value3"] .
1029
- )
1030
- },
1031
- "Property value with @included": {
1032
- input: %({
1033
- "@context": {
1034
- "@version": 1.1,
1035
- "@vocab": "http://example.org/"
1036
- },
1037
- "prop": {
1038
- "@type": "Foo",
1039
- "@included": {
1040
- "@type": "Bar"
1041
- }
1042
- }
1043
- }),
1044
- output: %(
1045
- [<http://example.org/prop> [a <http://example.org/Foo>]] .
1046
- [a <http://example.org/Bar>] .
1047
- )
1048
- },
1049
- "json.api example": {
1050
- input: %({
1051
- "@context": {
1052
- "@version": 1.1,
1053
- "@vocab": "http://example.org/vocab#",
1054
- "@base": "http://example.org/base/",
1055
- "id": "@id",
1056
- "type": "@type",
1057
- "data": "@nest",
1058
- "attributes": "@nest",
1059
- "links": "@nest",
1060
- "relationships": "@nest",
1061
- "included": "@included",
1062
- "self": {"@type": "@id"},
1063
- "related": {"@type": "@id"},
1064
- "comments": {
1065
- "@context": {
1066
- "data": null
1067
- }
1068
- }
1069
- },
1070
- "data": [{
1071
- "type": "articles",
1072
- "id": "1",
1073
- "attributes": {
1074
- "title": "JSON:API paints my bikeshed!"
1075
- },
1076
- "links": {
1077
- "self": "http://example.com/articles/1"
1078
- },
1079
- "relationships": {
1080
- "author": {
1081
- "links": {
1082
- "self": "http://example.com/articles/1/relationships/author",
1083
- "related": "http://example.com/articles/1/author"
1084
- },
1085
- "data": { "type": "people", "id": "9" }
1086
- },
1087
- "comments": {
1088
- "links": {
1089
- "self": "http://example.com/articles/1/relationships/comments",
1090
- "related": "http://example.com/articles/1/comments"
1091
- },
1092
- "data": [
1093
- { "type": "comments", "id": "5" },
1094
- { "type": "comments", "id": "12" }
1095
- ]
1096
- }
1097
- }
1098
- }],
1099
- "included": [{
1100
- "type": "people",
1101
- "id": "9",
1102
- "attributes": {
1103
- "first-name": "Dan",
1104
- "last-name": "Gebhardt",
1105
- "twitter": "dgeb"
1106
- },
1107
- "links": {
1108
- "self": "http://example.com/people/9"
1109
- }
1110
- }, {
1111
- "type": "comments",
1112
- "id": "5",
1113
- "attributes": {
1114
- "body": "First!"
1115
- },
1116
- "relationships": {
1117
- "author": {
1118
- "data": { "type": "people", "id": "2" }
1119
- }
1120
- },
1121
- "links": {
1122
- "self": "http://example.com/comments/5"
1123
- }
1124
- }, {
1125
- "type": "comments",
1126
- "id": "12",
1127
- "attributes": {
1128
- "body": "I like XML better"
1129
- },
1130
- "relationships": {
1131
- "author": {
1132
- "data": { "type": "people", "id": "9" }
1133
- }
1134
- },
1135
- "links": {
1136
- "self": "http://example.com/comments/12"
1137
- }
1138
- }]
1139
- }),
1140
- output: %(
1141
- <http://example.org/base/1> a <http://example.org/vocab#articles>;
1142
- <http://example.org/vocab#author> <http://example.org/base/9>;
1143
- <http://example.org/vocab#comments> [
1144
- <http://example.org/vocab#related> <http://example.com/articles/1/comments>;
1145
- <http://example.org/vocab#self> <http://example.com/articles/1/relationships/comments>
1146
- ];
1147
- <http://example.org/vocab#self> <http://example.com/articles/1>;
1148
- <http://example.org/vocab#title> "JSON:API paints my bikeshed!" .
1149
-
1150
- <http://example.org/base/12> a <http://example.org/vocab#comments>;
1151
- <http://example.org/vocab#author> <http://example.org/base/9>;
1152
- <http://example.org/vocab#body> "I like XML better";
1153
- <http://example.org/vocab#self> <http://example.com/comments/12> .
1154
-
1155
- <http://example.org/base/5> a <http://example.org/vocab#comments>;
1156
- <http://example.org/vocab#author> <http://example.org/base/2>;
1157
- <http://example.org/vocab#body> "First!";
1158
- <http://example.org/vocab#self> <http://example.com/comments/5> .
1159
-
1160
- <http://example.org/base/2> a <http://example.org/vocab#people> .
1161
-
1162
- <http://example.org/base/9> a <http://example.org/vocab#people>;
1163
- <http://example.org/vocab#first-name> "Dan";
1164
- <http://example.org/vocab#last-name> "Gebhardt";
1165
- <http://example.org/vocab#related> <http://example.com/articles/1/author>;
1166
- <http://example.org/vocab#self> <http://example.com/articles/1/relationships/author>,
1167
- <http://example.com/people/9>;
1168
- <http://example.org/vocab#twitter> "dgeb" .
1169
- )
1170
- },
1171
- }.each do |title, params|
1172
- it(title) {run_to_rdf params}
1173
- end
1174
- end
1175
-
1176
- context "advanced features" do
1177
- {
1178
- "number syntax (decimal)" =>
1179
- [
1180
- %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3}),
1181
- %q(_:a <http://example/measure#cups> "5.3E0"^^<http://www.w3.org/2001/XMLSchema#double> .)
1182
- ],
1183
- "number syntax (double)" =>
1184
- [
1185
- %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3e0}),
1186
- %q(_:a <http://example/measure#cups> "5.3E0"^^<http://www.w3.org/2001/XMLSchema#double> .)
1187
- ],
1188
- "number syntax (integer)" =>
1189
- [
1190
- %q({"@context": { "chem": "http://example/chem#"}, "chem:protons": 12}),
1191
- %q(_:a <http://example/chem#protons> "12"^^<http://www.w3.org/2001/XMLSchema#integer> .)
1192
- ],
1193
- "boolan syntax" =>
1194
- [
1195
- %q({"@context": { "sensor": "http://example/sensor#"}, "sensor:active": true}),
1196
- %q(_:a <http://example/sensor#active> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .)
1197
- ],
1198
- "Array top element" =>
1199
- [
1200
- %q([
1201
- {"@id": "http://example.com/#me", "@type": "http://xmlns.com/foaf/0.1/Person"},
1202
- {"@id": "http://example.com/#you", "@type": "http://xmlns.com/foaf/0.1/Person"}
1203
- ]),
1204
- %q(
1205
- <http://example.com/#me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1206
- <http://example.com/#you> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1207
- )
1208
- ],
1209
- "@graph with array of objects value" =>
1210
- [
1211
- %q({
1212
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
1213
- "@graph": [
1214
- {"@id": "http://example.com/#me", "@type": "foaf:Person"},
1215
- {"@id": "http://example.com/#you", "@type": "foaf:Person"}
1216
- ]
1217
- }),
1218
- %q(
1219
- <http://example.com/#me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1220
- <http://example.com/#you> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1221
- )
1222
- ],
1223
- "XMLLiteral" => [
1224
- %q({
1225
- "http://rdfs.org/sioc/ns#content": {
1226
- "@value": "foo",
1227
- "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
1228
- }
1229
- }),
1230
- %q(
1231
- [<http://rdfs.org/sioc/ns#content> "foo"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>] .
1232
- )
1233
- ],
1234
- }.each do |title, (js, ttl)|
1235
- it title do
1236
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1237
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1238
- end
1239
- end
1240
- end
1241
-
1242
- context "@direction" do
1243
- context "rdfDirection: null" do
1244
- {
1245
- "no language rtl": [
1246
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1247
- %q(_:a <http://example.org/label> "no language" .)
1248
- ],
1249
- "en-US rtl": [
1250
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1251
- %q(_:a <http://example.org/label> "en-US"@en-us .)
1252
- ]
1253
- }.each do |title, (js, ttl)|
1254
- it title do
1255
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1256
- expect(parse(js, rdfDirection: nil)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1257
- end
1258
- end
1259
- end
1260
-
1261
- context "rdfDirection: i18n-datatype" do
1262
- {
1263
- "no language rtl": [
1264
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1265
- %q(_:a <http://example.org/label> "no language"^^<https://www.w3.org/ns/i18n#_rtl> .)
1266
- ],
1267
- "en-US rtl": [
1268
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1269
- %q(_:a <http://example.org/label> "en-US"^^<https://www.w3.org/ns/i18n#en-us_rtl> .)
1270
- ]
1271
- }.each do |title, (js, ttl)|
1272
- it title do
1273
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1274
- expect(parse(js, rdfDirection: 'i18n-datatype')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1275
- end
1276
- end
1277
- end
1278
-
1279
- context "rdfDirection: compound-literal" do
1280
- {
1281
- "no language rtl": [
1282
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1283
- %q(
1284
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
1285
- _:a <http://example.org/label> [
1286
- rdf:value "no language";
1287
- rdf:direction "rtl"
1288
- ] .
1289
- )
1290
- ],
1291
- "en-US rtl": [
1292
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1293
- %q(
1294
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
1295
- _:a <http://example.org/label> [
1296
- rdf:value "en-US";
1297
- rdf:language "en-us";
1298
- rdf:direction "rtl"
1299
- ] .
1300
- )
1301
- ]
1302
- }.each do |title, (js, ttl)|
1303
- it title do
1304
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1305
- expect(parse(js, rdfDirection: 'compound-literal')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1306
- end
1307
- end
1308
- end
1309
- end
1310
-
1311
- context "JSON-LD-star" do
1312
- {
1313
- "node with embedded subject without rdfstar option": {
1314
- input: %({
1315
- "@id": {
1316
- "@id": "ex:rei",
1317
- "ex:prop": "value"
1318
- },
1319
- "ex:prop": "value2"
1320
- }),
1321
- exception: JSON::LD::JsonLdError::InvalidIdValue
1322
- },
1323
- }.each do |title, params|
1324
- it(title) {run_to_rdf params}
1325
- end
1326
-
1327
- {
1328
- "node with embedded subject having no @id": {
1329
- input: %({
1330
- "@id": {
1331
- "ex:prop": "value"
1332
- },
1333
- "ex:prop": "value2"
1334
- }),
1335
- expected: %(
1336
- <<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
1337
- ),
1338
- },
1339
- "node with embedded subject having IRI @id": {
1340
- input: %({
1341
- "@id": {
1342
- "@id": "ex:rei",
1343
- "ex:prop": "value"
1344
- },
1345
- "ex:prop": "value2"
1346
- }),
1347
- expected: %(
1348
- <<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
1349
- ),
1350
- },
1351
- "node with embedded subject having BNode @id": {
1352
- input: %({
1353
- "@id": {
1354
- "@id": "_:rei",
1355
- "ex:prop": "value"
1356
- },
1357
- "ex:prop": "value2"
1358
- }),
1359
- expected: %(
1360
- <<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
1361
- ),
1362
- },
1363
- "node with embedded subject having a type": {
1364
- input: %({
1365
- "@id": {
1366
- "@id": "ex:rei",
1367
- "@type": "ex:Type"
1368
- },
1369
- "ex:prop": "value2"
1370
- }),
1371
- expected: %(
1372
- <<<ex:rei> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <ex:Type>>> <ex:prop> "value2" .
1373
- ),
1374
- },
1375
- "node with embedded subject having an IRI value": {
1376
- input: %({
1377
- "@id": {
1378
- "@id": "ex:rei",
1379
- "ex:prop": {"@id": "ex:value"}
1380
- },
1381
- "ex:prop": "value2"
1382
- }),
1383
- expected: %(
1384
- <<<ex:rei> <ex:prop> <ex:value>>> <ex:prop> "value2" .
1385
- ),
1386
- },
1387
- "node with embedded subject having an BNode value": {
1388
- input: %({
1389
- "@id": {
1390
- "@id": "ex:rei",
1391
- "ex:prop": {"@id": "_:value"}
1392
- },
1393
- "ex:prop": "value2"
1394
- }),
1395
- expected: %(
1396
- <<<ex:rei> <ex:prop> _:b0>> <ex:prop> "value2" .
1397
- ),
1398
- },
1399
- "node with recursive embedded subject": {
1400
- input: %({
1401
- "@id": {
1402
- "@id": {
1403
- "@id": "ex:rei",
1404
- "ex:prop": "value3"
1405
- },
1406
- "ex:prop": "value"
1407
- },
1408
- "ex:prop": "value2"
1409
- }),
1410
- expected: %(
1411
- <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
1412
- ),
1413
- },
1414
- "illegal node with subject having no property": {
1415
- input: %({
1416
- "@id": {
1417
- "@id": "ex:rei"
1418
- },
1419
- "ex:prop": "value3"
1420
- }),
1421
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1422
- },
1423
- "illegal node with subject having multiple properties": {
1424
- input: %({
1425
- "@id": {
1426
- "@id": "ex:rei",
1427
- "ex:prop": ["value1", "value2"]
1428
- },
1429
- "ex:prop": "value3"
1430
- }),
1431
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1432
- },
1433
- "illegal node with subject having multiple types": {
1434
- input: %({
1435
- "@id": {
1436
- "@id": "ex:rei",
1437
- "@type": ["ex:Type1", "ex:Type2"]
1438
- },
1439
- "ex:prop": "value3"
1440
- }),
1441
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1442
- },
1443
- "illegal node with subject having type and property": {
1444
- input: %({
1445
- "@id": {
1446
- "@id": "ex:rei",
1447
- "@type": "ex:Type",
1448
- "ex:prop": "value"
1449
- },
1450
- "ex:prop": "value2"
1451
- }),
1452
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1453
- },
1454
- "node with embedded object": {
1455
- input: %({
1456
- "@id": "ex:subj",
1457
- "ex:value": {
1458
- "@id": {
1459
- "@id": "ex:rei",
1460
- "ex:prop": "value"
1461
- }
1462
- }
1463
- }),
1464
- expected: %(
1465
- <ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
1466
- ),
1467
- },
1468
- "node with embedded object having properties": {
1469
- input: %({
1470
- "@id": "ex:subj",
1471
- "ex:value": {
1472
- "@id": {
1473
- "@id": "ex:rei",
1474
- "ex:prop": "value"
1475
- },
1476
- "ex:prop": "value2"
1477
- }
1478
- }),
1479
- expected: %(
1480
- <ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
1481
- <<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
1482
- ),
1483
- },
1484
- "node with recursive embedded object": {
1485
- input: %({
1486
- "@id": "ex:subj",
1487
- "ex:value": {
1488
- "@id": {
1489
- "@id": {
1490
- "@id": "ex:rei",
1491
- "ex:prop": "value3"
1492
- },
1493
- "ex:prop": "value"
1494
- },
1495
- "ex:prop": "value2"
1496
- }
1497
- }),
1498
- expected: %(
1499
- <ex:subj> <ex:value> <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> .
1500
- <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
1501
- ),
1502
- },
1503
- }.each do |title, params|
1504
- context(title) do
1505
- it "Generates statements" do
1506
- output_graph = RDF::Graph.new {|g| g << RDF::NTriples::Reader.new(params[:expected], rdfstar: true)}
1507
- run_to_rdf params.merge(rdfstar: true, output: output_graph)
1508
- end if params[:expected]
1509
-
1510
- it "Exception" do
1511
- run_to_rdf params.merge(rdfstar: true)
1512
- end if params[:exception]
1513
- end
1514
- end
1515
- end
1516
-
1517
- context "exceptions" do
1518
- {
1519
- "Invalid subject" => {
1520
- input: %({
1521
- "@id": "http://example.com/a b",
1522
- "http://example.com/foo": "bar"
1523
- }),
1524
- output: %()
1525
- },
1526
- "Invalid predicate" => {
1527
- input: %({
1528
- "@id": "http://example.com/foo",
1529
- "http://example.com/a b": "bar"
1530
- }),
1531
- output: %()
1532
- },
1533
- "Invalid object" => {
1534
- input: %({
1535
- "@id": "http://example.com/foo",
1536
- "http://example.com/bar": {"@id": "http://example.com/baz z"}
1537
- }),
1538
- output: %()
1539
- },
1540
- "Invalid type" => {
1541
- input: %({
1542
- "@id": "http://example.com/foo",
1543
- "@type": ["http://example.com/bar", "relative"]
1544
- }),
1545
- output: %(<http://example.com/foo> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/bar> .)
1546
- },
1547
- "Invalid language" => {
1548
- input: %({
1549
- "@id": "http://example.com/foo",
1550
- "http://example.com/bar": {"@value": "bar", "@language": "a b"}
1551
- }),
1552
- output: %(),
1553
- write: "@language must be valid BCP47"
1554
- },
1555
- "Invalid datatype" => {
1556
- input: %({
1557
- "@id": "http://example.com/foo",
1558
- "http://example.com/bar": {"@value": "bar", "@type": "http://example.com/baz z"}
1559
- }),
1560
- exception: JSON::LD::JsonLdError::InvalidTypedValue
1561
- },
1562
- "Injected IRIs check" => {
1563
- input: %({
1564
- "@id": "http://foo/> <http://bar/> <http://baz> .\n<data:little> <data:bobby> <data:tables> .\n<data:in-ur-base",
1565
- "http://killin/#yer": "dudes"
1566
- }),
1567
- output: %(),
1568
- pending: "jruby"
1569
- },
1570
- }.each do |title, params|
1571
- it(title) do
1572
- pending params[:pending] if params[:pending] == RUBY_ENGINE
1573
- run_to_rdf params
1574
- end
1575
- end
1576
- end
1577
- end
1578
-
1579
- context "html" do
1580
- {
1581
- "Transforms embedded JSON-LD script element": {
1582
- input: %(
1583
- <html>
1584
- <head>
1585
- <script type="application/ld+json">
1586
- {
1587
- "@context": {
1588
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1589
- },
1590
- "foo": [{"@value": "bar"}]
1591
- }
1592
- </script>
1593
- </head>
1594
- </html>),
1595
- output: %([ <http://example.com/foo> ( "bar")] .)
1596
- },
1597
- "Transforms first script element with extractAllScripts: false": {
1598
- input: %(
1599
- <html>
1600
- <head>
1601
- <script type="application/ld+json">
1602
- {
1603
- "@context": {
1604
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1605
- },
1606
- "foo": [{"@value": "bar"}]
1607
- }
1608
- </script>
1609
- <script type="application/ld+json">
1610
- {
1611
- "@context": {"ex": "http://example.com/"},
1612
- "@graph": [
1613
- {"ex:foo": {"@value": "foo"}},
1614
- {"ex:bar": {"@value": "bar"}}
1615
- ]
1616
- }
1617
- </script>
1618
- </head>
1619
- </html>),
1620
- output: %([ <http://example.com/foo> ( "bar")] .),
1621
- extractAllScripts: false
1622
- },
1623
- "Transforms targeted script element": {
1624
- input: %(
1625
- <html>
1626
- <head>
1627
- <script id="first" type="application/ld+json">
1628
- {
1629
- "@context": {
1630
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1631
- },
1632
- "foo": [{"@value": "bar"}]
1633
- }
1634
- </script>
1635
- <script id="second" type="application/ld+json">
1636
- {
1637
- "@context": {"ex": "http://example.com/"},
1638
- "@graph": [
1639
- {"ex:foo": {"@value": "foo"}},
1640
- {"ex:bar": {"@value": "bar"}}
1641
- ]
1642
- }
1643
- </script>
1644
- </head>
1645
- </html>),
1646
- output: %(
1647
- [ <http://example.com/foo> "foo"] .
1648
- [ <http://example.com/bar> "bar"] .
1649
- ),
1650
- base: "http://example.org/doc#second"
1651
- },
1652
- }.each do |title, params|
1653
- it(title) do
1654
- params[:input] = StringIO.new(params[:input])
1655
- params[:input].send(:define_singleton_method, :content_type) {"text/html"}
1656
- run_to_rdf params.merge(validate: true)
1657
- end
1658
- end
1659
- end
1660
-
1661
- def parse(input, **options)
1662
- graph = options[:graph] || RDF::Graph.new
1663
- options = {logger: logger, validate: true, canonicalize: false}.merge(options)
1664
- JSON::LD::API.toRdf(StringIO.new(input), rename_bnodes: false, **options) {|st| graph << st}
1665
- graph
1666
- end
1667
-
1668
- def run_to_rdf(params)
1669
- input, output = params[:input], params[:output]
1670
- graph = params[:graph] || RDF::Graph.new
1671
- input = StringIO.new(input) if input.is_a?(String)
1672
- pending params.fetch(:pending, "test implementation") unless input
1673
- if params[:exception]
1674
- expect {JSON::LD::API.toRdf(input, **params)}.to raise_error(params[:exception])
1675
- else
1676
- if params[:write]
1677
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.to write(params[:write]).to(:error)
1678
- else
1679
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.not_to write.to(:error)
1680
- end
1681
- expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input)
1682
- end
1683
- end
1684
- end