json-ld 3.2.3 → 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 -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/to_rdf_spec.rb DELETED
@@ -1,1551 +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
- end
413
-
414
- context "prefixes" do
415
- {
416
- "empty suffix" => [
417
- %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:": "bar"}),
418
- %q(_:a <http://example.com/default#> "bar"^^xsd:string .)
419
- ],
420
- "prefix:suffix" => [
421
- %q({"@context": {"prefix": "http://example.com/default#"}, "prefix:foo": "bar"}),
422
- %q(_:a <http://example.com/default#foo> "bar"^^xsd:string .)
423
- ]
424
- }.each_pair do |title, (js, ttl)|
425
- it title do
426
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
427
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
428
- end
429
- end
430
- end
431
-
432
- context "overriding keywords" do
433
- {
434
- "'url' for @id, 'a' for @type" => [
435
- %q({
436
- "@context": {"url": "@id", "a": "@type", "name": "http://schema.org/name"},
437
- "url": "http://example.com/about#gregg",
438
- "a": "http://schema.org/Person",
439
- "name": "Gregg Kellogg"
440
- }),
441
- %q(
442
- <http://example.com/about#gregg> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> .
443
- <http://example.com/about#gregg> <http://schema.org/name> "Gregg Kellogg"^^xsd:string .
444
- )
445
- ],
446
- }.each do |title, (js, ttl)|
447
- it title do
448
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
449
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
450
- end
451
- end
452
- end
453
-
454
- context "chaining" do
455
- {
456
- "explicit subject" =>
457
- [
458
- %q({
459
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
460
- "@id": "http://greggkellogg.net/foaf#me",
461
- "foaf:knows": {
462
- "@id": "http://www.ivan-herman.net/foaf#me",
463
- "foaf:name": "Ivan Herman"
464
- }
465
- }),
466
- %q(
467
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.ivan-herman.net/foaf#me> .
468
- <http://www.ivan-herman.net/foaf#me> <http://xmlns.com/foaf/0.1/name> "Ivan Herman" .
469
- )
470
- ],
471
- "implicit subject" =>
472
- [
473
- %q({
474
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
475
- "@id": "http://greggkellogg.net/foaf#me",
476
- "foaf:knows": {
477
- "foaf:name": "Manu Sporny"
478
- }
479
- }),
480
- %q(
481
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
482
- _:a <http://xmlns.com/foaf/0.1/name> "Manu Sporny"^^xsd:string .
483
- )
484
- ],
485
- }.each do |title, (js, ttl)|
486
- it title do
487
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
488
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
489
- end
490
- end
491
- end
492
-
493
- context "multiple values" do
494
- {
495
- "literals" =>
496
- [
497
- %q({
498
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
499
- "@id": "http://greggkellogg.net/foaf#me",
500
- "foaf:knows": ["Manu Sporny", "Ivan Herman"]
501
- }),
502
- %q(
503
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> "Manu Sporny" .
504
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> "Ivan Herman" .
505
- )
506
- ],
507
- }.each do |title, (js, ttl)|
508
- it title do
509
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
510
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
511
- end
512
- end
513
- end
514
-
515
- context "lists" do
516
- {
517
- "Empty" => [
518
- %q({
519
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
520
- "@id": "http://greggkellogg.net/foaf#me",
521
- "foaf:knows": {"@list": []}
522
- }),
523
- %q(
524
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
525
- )
526
- ],
527
- "single value" => [
528
- %q({
529
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
530
- "@id": "http://greggkellogg.net/foaf#me",
531
- "foaf:knows": {"@list": ["Manu Sporny"]}
532
- }),
533
- %q(
534
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
535
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
536
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
537
- )
538
- ],
539
- "single value (with coercion)" => [
540
- %q({
541
- "@context": {
542
- "foaf": "http://xmlns.com/foaf/0.1/",
543
- "foaf:knows": { "@container": "@list"}
544
- },
545
- "@id": "http://greggkellogg.net/foaf#me",
546
- "foaf:knows": ["Manu Sporny"]
547
- }),
548
- %q(
549
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
550
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
551
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
552
- )
553
- ],
554
- "multiple values" => [
555
- %q({
556
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
557
- "@id": "http://greggkellogg.net/foaf#me",
558
- "foaf:knows": {"@list": ["Manu Sporny", "Dave Longley"]}
559
- }),
560
- %q(
561
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> _:a .
562
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Manu Sporny"^^xsd:string .
563
- _:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b .
564
- _:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "Dave Longley"^^xsd:string .
565
- _:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
566
- )
567
- ],
568
- "@list containing @list" => [
569
- %q({
570
- "@id": "http://example/A",
571
- "http://example.com/foo": {"@list": [{"@list": ["baz"]}]}
572
- }),
573
- %q(
574
- <http://example/A> <http://example.com/foo> (("baz")) .
575
- )
576
- ],
577
- "@list containing empty @list" => [
578
- %({
579
- "@id": "http://example/A",
580
- "http://example.com/foo": {"@list": [{"@list": []}]}
581
- }),
582
- %q(
583
- <http://example/A> <http://example.com/foo> (()) .
584
- )
585
- ],
586
- }.each do |title, (js, ttl)|
587
- it title do
588
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
589
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
590
- end
591
- end
592
- end
593
-
594
- context "context" do
595
- {
596
- "@id coersion" =>
597
- [
598
- %q({
599
- "@context": {
600
- "knows": {"@id": "http://xmlns.com/foaf/0.1/knows", "@type": "@id"}
601
- },
602
- "@id": "http://greggkellogg.net/foaf#me",
603
- "knows": "http://www.ivan-herman.net/foaf#me"
604
- }),
605
- %q(
606
- <http://greggkellogg.net/foaf#me> <http://xmlns.com/foaf/0.1/knows> <http://www.ivan-herman.net/foaf#me> .
607
- )
608
- ],
609
- "datatype coersion" =>
610
- [
611
- %q({
612
- "@context": {
613
- "dcterms": "http://purl.org/dc/terms/",
614
- "xsd": "http://www.w3.org/2001/XMLSchema#",
615
- "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:date"}
616
- },
617
- "@id": "http://greggkellogg.net/foaf#me",
618
- "created": "1957-02-27"
619
- }),
620
- %q(
621
- <http://greggkellogg.net/foaf#me> <http://purl.org/dc/terms/created> "1957-02-27"^^<http://www.w3.org/2001/XMLSchema#date> .
622
- )
623
- ],
624
- "sub-objects with context" => [
625
- %q({
626
- "@context": {"foo": "http://example.com/foo"},
627
- "foo": {
628
- "@context": {"foo": "http://example.org/foo"},
629
- "foo": "bar"
630
- }
631
- }),
632
- %q(
633
- _:a <http://example.com/foo> _:b .
634
- _:b <http://example.org/foo> "bar"^^xsd:string .
635
- )
636
- ],
637
- "contexts with a list processed in order" => [
638
- %q({
639
- "@context": [
640
- {"foo": "http://example.com/foo"},
641
- {"foo": "http://example.org/foo"}
642
- ],
643
- "foo": "bar"
644
- }),
645
- %q(
646
- _:b <http://example.org/foo> "bar"^^xsd:string .
647
- )
648
- ],
649
- "term definition resolves term as IRI" => [
650
- %q({
651
- "@context": [
652
- {"foo": "http://example.com/foo"},
653
- {"bar": "foo"}
654
- ],
655
- "bar": "bar"
656
- }),
657
- %q(
658
- _:b <http://example.com/foo> "bar"^^xsd:string .
659
- )
660
- ],
661
- "term definition resolves prefix as IRI" => [
662
- %q({
663
- "@context": [
664
- {"foo": "http://example.com/foo#"},
665
- {"bar": "foo:bar"}
666
- ],
667
- "bar": "bar"
668
- }),
669
- %q(
670
- _:b <http://example.com/foo#bar> "bar"^^xsd:string .
671
- )
672
- ],
673
- "@language" => [
674
- %q({
675
- "@context": {
676
- "foo": "http://example.com/foo#",
677
- "@language": "en"
678
- },
679
- "foo:bar": "baz"
680
- }),
681
- %q(
682
- _:a <http://example.com/foo#bar> "baz"@en .
683
- )
684
- ],
685
- "@language with override" => [
686
- %q({
687
- "@context": {
688
- "foo": "http://example.com/foo#",
689
- "@language": "en"
690
- },
691
- "foo:bar": {"@value": "baz", "@language": "fr"}
692
- }),
693
- %q(
694
- _:a <http://example.com/foo#bar> "baz"@fr .
695
- )
696
- ],
697
- "@language with plain" => [
698
- %q({
699
- "@context": {
700
- "foo": "http://example.com/foo#",
701
- "@language": "en"
702
- },
703
- "foo:bar": {"@value": "baz"}
704
- }),
705
- %q(
706
- _:a <http://example.com/foo#bar> "baz"^^xsd:string .
707
- )
708
- ],
709
- }.each do |title, (js, ttl)|
710
- it title do
711
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
712
- expect(parse(js)).to be_equivalent_graph(ttl, base: "http://example/", logger: logger, inputDocument: js)
713
- end
714
- end
715
-
716
- context "coercion" do
717
- context "term def with @id + @type" do
718
- {
719
- "dt with term" => [
720
- %q({
721
- "@context": [
722
- {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"},
723
- {"foo": {"@id": "term", "@type": "date"}}
724
- ],
725
- "foo": "bar"
726
- }),
727
- %q(
728
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
729
- [ <http://example.org/foo#> "bar"^^xsd:date ] .
730
- )
731
- ],
732
- "@id with term" => [
733
- %q({
734
- "@context": [
735
- {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id"}}
736
- ],
737
- "foo": "http://example.org/foo#bar"
738
- }),
739
- %q(
740
- _:a <http://example.org/foo#bar> <http://example.org/foo#bar> .
741
- )
742
- ],
743
- "coercion without term definition" => [
744
- %q({
745
- "@context": [
746
- {
747
- "xsd": "http://www.w3.org/2001/XMLSchema#",
748
- "dc": "http://purl.org/dc/terms/"
749
- },
750
- {
751
- "dc:date": {"@type": "xsd:date"}
752
- }
753
- ],
754
- "dc:date": "2011-11-23"
755
- }),
756
- %q(
757
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
758
- @prefix dc: <http://purl.org/dc/terms/> .
759
- [ dc:date "2011-11-23"^^xsd:date] .
760
- )
761
- ],
762
- }.each do |title, (js, ttl)|
763
- it title do
764
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
765
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
766
- end
767
- end
768
- end
769
- end
770
-
771
- context "lists" do
772
- context "term def with @id + @type + @container" do
773
- {
774
- "dt with term" => [
775
- %q({
776
- "@context": [
777
- {"date": "http://www.w3.org/2001/XMLSchema#date", "term": "http://example.org/foo#"},
778
- {"foo": {"@id": "term", "@type": "date", "@container": "@list"}}
779
- ],
780
- "foo": ["bar"]
781
- }),
782
- %q(
783
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
784
- [ <http://example.org/foo#> ("bar"^^xsd:date) ] .
785
- )
786
- ],
787
- "@id with term" => [
788
- %q({
789
- "@context": [
790
- {"foo": {"@id": "http://example.org/foo#bar", "@type": "@id", "@container": "@list"}}
791
- ],
792
- "foo": ["http://example.org/foo#bar"]
793
- }),
794
- %q(
795
- _:a <http://example.org/foo#bar> (<http://example.org/foo#bar>) .
796
- )
797
- ],
798
- }.each do |title, (js, ttl)|
799
- it title do
800
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
801
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
802
- end
803
- end
804
- end
805
- end
806
- end
807
-
808
- context "blank node predicates" do
809
- subject {%q({"@id": "http://example/subj", "_:foo": "bar"})}
810
-
811
- it "outputs statements with blank node predicates if :produceGeneralizedRdf is true" do
812
- expect do
813
- graph = parse(subject, produceGeneralizedRdf: true)
814
- expect(graph.count).to eq 1
815
- end.to write("[DEPRECATION]").to(:error)
816
- end
817
-
818
- it "rejects statements with blank node predicates if :produceGeneralizedRdf is false" do
819
- expect do
820
- graph = parse(subject, produceGeneralizedRdf: false)
821
- expect(graph.count).to eq 0
822
- end.to write("[DEPRECATION]").to(:error)
823
- end
824
- end
825
-
826
- context "@included" do
827
- {
828
- "Basic Included array": {
829
- input: %({
830
- "@context": {
831
- "@version": 1.1,
832
- "@vocab": "http://example.org/"
833
- },
834
- "prop": "value",
835
- "@included": [{
836
- "prop": "value2"
837
- }]
838
- }),
839
- output: %(
840
- [<http://example.org/prop> "value"] .
841
- [<http://example.org/prop> "value2"] .
842
- )
843
- },
844
- "Basic Included object": {
845
- input: %({
846
- "@context": {
847
- "@version": 1.1,
848
- "@vocab": "http://example.org/"
849
- },
850
- "prop": "value",
851
- "@included": {
852
- "prop": "value2"
853
- }
854
- }),
855
- output: %(
856
- [<http://example.org/prop> "value"] .
857
- [<http://example.org/prop> "value2"] .
858
- )
859
- },
860
- "Multiple properties mapping to @included are folded together": {
861
- input: %({
862
- "@context": {
863
- "@version": 1.1,
864
- "@vocab": "http://example.org/",
865
- "included1": "@included",
866
- "included2": "@included"
867
- },
868
- "included1": {"prop": "value1"},
869
- "included2": {"prop": "value2"}
870
- }),
871
- output: %(
872
- [<http://example.org/prop> "value1"] .
873
- [<http://example.org/prop> "value2"] .
874
- )
875
- },
876
- "Included containing @included": {
877
- input: %({
878
- "@context": {
879
- "@version": 1.1,
880
- "@vocab": "http://example.org/"
881
- },
882
- "prop": "value",
883
- "@included": {
884
- "prop": "value2",
885
- "@included": {
886
- "prop": "value3"
887
- }
888
- }
889
- }),
890
- output: %(
891
- [<http://example.org/prop> "value"] .
892
-
893
- [<http://example.org/prop> "value2"] .
894
-
895
- [<http://example.org/prop> "value3"] .
896
- )
897
- },
898
- "Property value with @included": {
899
- input: %({
900
- "@context": {
901
- "@version": 1.1,
902
- "@vocab": "http://example.org/"
903
- },
904
- "prop": {
905
- "@type": "Foo",
906
- "@included": {
907
- "@type": "Bar"
908
- }
909
- }
910
- }),
911
- output: %(
912
- [<http://example.org/prop> [a <http://example.org/Foo>]] .
913
- [a <http://example.org/Bar>] .
914
- )
915
- },
916
- "json.api example": {
917
- input: %({
918
- "@context": {
919
- "@version": 1.1,
920
- "@vocab": "http://example.org/vocab#",
921
- "@base": "http://example.org/base/",
922
- "id": "@id",
923
- "type": "@type",
924
- "data": "@nest",
925
- "attributes": "@nest",
926
- "links": "@nest",
927
- "relationships": "@nest",
928
- "included": "@included",
929
- "self": {"@type": "@id"},
930
- "related": {"@type": "@id"},
931
- "comments": {
932
- "@context": {
933
- "data": null
934
- }
935
- }
936
- },
937
- "data": [{
938
- "type": "articles",
939
- "id": "1",
940
- "attributes": {
941
- "title": "JSON:API paints my bikeshed!"
942
- },
943
- "links": {
944
- "self": "http://example.com/articles/1"
945
- },
946
- "relationships": {
947
- "author": {
948
- "links": {
949
- "self": "http://example.com/articles/1/relationships/author",
950
- "related": "http://example.com/articles/1/author"
951
- },
952
- "data": { "type": "people", "id": "9" }
953
- },
954
- "comments": {
955
- "links": {
956
- "self": "http://example.com/articles/1/relationships/comments",
957
- "related": "http://example.com/articles/1/comments"
958
- },
959
- "data": [
960
- { "type": "comments", "id": "5" },
961
- { "type": "comments", "id": "12" }
962
- ]
963
- }
964
- }
965
- }],
966
- "included": [{
967
- "type": "people",
968
- "id": "9",
969
- "attributes": {
970
- "first-name": "Dan",
971
- "last-name": "Gebhardt",
972
- "twitter": "dgeb"
973
- },
974
- "links": {
975
- "self": "http://example.com/people/9"
976
- }
977
- }, {
978
- "type": "comments",
979
- "id": "5",
980
- "attributes": {
981
- "body": "First!"
982
- },
983
- "relationships": {
984
- "author": {
985
- "data": { "type": "people", "id": "2" }
986
- }
987
- },
988
- "links": {
989
- "self": "http://example.com/comments/5"
990
- }
991
- }, {
992
- "type": "comments",
993
- "id": "12",
994
- "attributes": {
995
- "body": "I like XML better"
996
- },
997
- "relationships": {
998
- "author": {
999
- "data": { "type": "people", "id": "9" }
1000
- }
1001
- },
1002
- "links": {
1003
- "self": "http://example.com/comments/12"
1004
- }
1005
- }]
1006
- }),
1007
- output: %(
1008
- <http://example.org/base/1> a <http://example.org/vocab#articles>;
1009
- <http://example.org/vocab#author> <http://example.org/base/9>;
1010
- <http://example.org/vocab#comments> [
1011
- <http://example.org/vocab#related> <http://example.com/articles/1/comments>;
1012
- <http://example.org/vocab#self> <http://example.com/articles/1/relationships/comments>
1013
- ];
1014
- <http://example.org/vocab#self> <http://example.com/articles/1>;
1015
- <http://example.org/vocab#title> "JSON:API paints my bikeshed!" .
1016
-
1017
- <http://example.org/base/12> a <http://example.org/vocab#comments>;
1018
- <http://example.org/vocab#author> <http://example.org/base/9>;
1019
- <http://example.org/vocab#body> "I like XML better";
1020
- <http://example.org/vocab#self> <http://example.com/comments/12> .
1021
-
1022
- <http://example.org/base/5> a <http://example.org/vocab#comments>;
1023
- <http://example.org/vocab#author> <http://example.org/base/2>;
1024
- <http://example.org/vocab#body> "First!";
1025
- <http://example.org/vocab#self> <http://example.com/comments/5> .
1026
-
1027
- <http://example.org/base/2> a <http://example.org/vocab#people> .
1028
-
1029
- <http://example.org/base/9> a <http://example.org/vocab#people>;
1030
- <http://example.org/vocab#first-name> "Dan";
1031
- <http://example.org/vocab#last-name> "Gebhardt";
1032
- <http://example.org/vocab#related> <http://example.com/articles/1/author>;
1033
- <http://example.org/vocab#self> <http://example.com/articles/1/relationships/author>,
1034
- <http://example.com/people/9>;
1035
- <http://example.org/vocab#twitter> "dgeb" .
1036
- )
1037
- },
1038
- }.each do |title, params|
1039
- it(title) {run_to_rdf params}
1040
- end
1041
- end
1042
-
1043
- context "advanced features" do
1044
- {
1045
- "number syntax (decimal)" =>
1046
- [
1047
- %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3}),
1048
- %q(_:a <http://example/measure#cups> "5.3E0"^^<http://www.w3.org/2001/XMLSchema#double> .)
1049
- ],
1050
- "number syntax (double)" =>
1051
- [
1052
- %q({"@context": { "measure": "http://example/measure#"}, "measure:cups": 5.3e0}),
1053
- %q(_:a <http://example/measure#cups> "5.3E0"^^<http://www.w3.org/2001/XMLSchema#double> .)
1054
- ],
1055
- "number syntax (integer)" =>
1056
- [
1057
- %q({"@context": { "chem": "http://example/chem#"}, "chem:protons": 12}),
1058
- %q(_:a <http://example/chem#protons> "12"^^<http://www.w3.org/2001/XMLSchema#integer> .)
1059
- ],
1060
- "boolan syntax" =>
1061
- [
1062
- %q({"@context": { "sensor": "http://example/sensor#"}, "sensor:active": true}),
1063
- %q(_:a <http://example/sensor#active> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .)
1064
- ],
1065
- "Array top element" =>
1066
- [
1067
- %q([
1068
- {"@id": "http://example.com/#me", "@type": "http://xmlns.com/foaf/0.1/Person"},
1069
- {"@id": "http://example.com/#you", "@type": "http://xmlns.com/foaf/0.1/Person"}
1070
- ]),
1071
- %q(
1072
- <http://example.com/#me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1073
- <http://example.com/#you> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1074
- )
1075
- ],
1076
- "@graph with array of objects value" =>
1077
- [
1078
- %q({
1079
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
1080
- "@graph": [
1081
- {"@id": "http://example.com/#me", "@type": "foaf:Person"},
1082
- {"@id": "http://example.com/#you", "@type": "foaf:Person"}
1083
- ]
1084
- }),
1085
- %q(
1086
- <http://example.com/#me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1087
- <http://example.com/#you> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
1088
- )
1089
- ],
1090
- "XMLLiteral" => [
1091
- %q({
1092
- "http://rdfs.org/sioc/ns#content": {
1093
- "@value": "foo",
1094
- "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
1095
- }
1096
- }),
1097
- %q(
1098
- [<http://rdfs.org/sioc/ns#content> "foo"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>] .
1099
- )
1100
- ],
1101
- }.each do |title, (js, ttl)|
1102
- it title do
1103
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1104
- expect(parse(js)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1105
- end
1106
- end
1107
- end
1108
-
1109
- context "@direction" do
1110
- context "rdfDirection: null" do
1111
- {
1112
- "no language rtl": [
1113
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1114
- %q(_:a <http://example.org/label> "no language" .)
1115
- ],
1116
- "en-US rtl": [
1117
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1118
- %q(_:a <http://example.org/label> "en-US"@en-us .)
1119
- ]
1120
- }.each do |title, (js, ttl)|
1121
- it title do
1122
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1123
- expect(parse(js, rdfDirection: nil)).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1124
- end
1125
- end
1126
- end
1127
-
1128
- context "rdfDirection: i18n-datatype" do
1129
- {
1130
- "no language rtl": [
1131
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1132
- %q(_:a <http://example.org/label> "no language"^^<https://www.w3.org/ns/i18n#_rtl> .)
1133
- ],
1134
- "en-US rtl": [
1135
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1136
- %q(_:a <http://example.org/label> "en-US"^^<https://www.w3.org/ns/i18n#en-us_rtl> .)
1137
- ]
1138
- }.each do |title, (js, ttl)|
1139
- it title do
1140
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1141
- expect(parse(js, rdfDirection: 'i18n-datatype')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1142
- end
1143
- end
1144
- end
1145
-
1146
- context "rdfDirection: compound-literal" do
1147
- {
1148
- "no language rtl": [
1149
- %q({"http://example.org/label": {"@value": "no language", "@direction": "rtl"}}),
1150
- %q(
1151
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
1152
- _:a <http://example.org/label> [
1153
- rdf:value "no language";
1154
- rdf:direction "rtl"
1155
- ] .
1156
- )
1157
- ],
1158
- "en-US rtl": [
1159
- %q({"http://example.org/label": {"@value": "en-US", "@language": "en-US", "@direction": "rtl"}}),
1160
- %q(
1161
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
1162
- _:a <http://example.org/label> [
1163
- rdf:value "en-US";
1164
- rdf:language "en-us";
1165
- rdf:direction "rtl"
1166
- ] .
1167
- )
1168
- ]
1169
- }.each do |title, (js, ttl)|
1170
- it title do
1171
- ttl = "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{ttl}"
1172
- expect(parse(js, rdfDirection: 'compound-literal')).to be_equivalent_graph(ttl, logger: logger, inputDocument: js)
1173
- end
1174
- end
1175
- end
1176
- end
1177
-
1178
- context "JSON-LD-star" do
1179
- {
1180
- "node with embedded subject without rdfstar option": {
1181
- input: %({
1182
- "@id": {
1183
- "@id": "ex:rei",
1184
- "ex:prop": "value"
1185
- },
1186
- "ex:prop": "value2"
1187
- }),
1188
- exception: JSON::LD::JsonLdError::InvalidIdValue
1189
- },
1190
- }.each do |title, params|
1191
- it(title) {run_to_rdf params}
1192
- end
1193
-
1194
- {
1195
- "node with embedded subject having no @id": {
1196
- input: %({
1197
- "@id": {
1198
- "ex:prop": "value"
1199
- },
1200
- "ex:prop": "value2"
1201
- }),
1202
- expected: %(
1203
- <<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
1204
- ),
1205
- },
1206
- "node with embedded subject having IRI @id": {
1207
- input: %({
1208
- "@id": {
1209
- "@id": "ex:rei",
1210
- "ex:prop": "value"
1211
- },
1212
- "ex:prop": "value2"
1213
- }),
1214
- expected: %(
1215
- <<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
1216
- ),
1217
- },
1218
- "node with embedded subject having BNode @id": {
1219
- input: %({
1220
- "@id": {
1221
- "@id": "_:rei",
1222
- "ex:prop": "value"
1223
- },
1224
- "ex:prop": "value2"
1225
- }),
1226
- expected: %(
1227
- <<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
1228
- ),
1229
- },
1230
- "node with embedded subject having a type": {
1231
- input: %({
1232
- "@id": {
1233
- "@id": "ex:rei",
1234
- "@type": "ex:Type"
1235
- },
1236
- "ex:prop": "value2"
1237
- }),
1238
- expected: %(
1239
- <<<ex:rei> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <ex:Type>>> <ex:prop> "value2" .
1240
- ),
1241
- },
1242
- "node with embedded subject having an IRI value": {
1243
- input: %({
1244
- "@id": {
1245
- "@id": "ex:rei",
1246
- "ex:prop": {"@id": "ex:value"}
1247
- },
1248
- "ex:prop": "value2"
1249
- }),
1250
- expected: %(
1251
- <<<ex:rei> <ex:prop> <ex:value>>> <ex:prop> "value2" .
1252
- ),
1253
- },
1254
- "node with embedded subject having an BNode value": {
1255
- input: %({
1256
- "@id": {
1257
- "@id": "ex:rei",
1258
- "ex:prop": {"@id": "_:value"}
1259
- },
1260
- "ex:prop": "value2"
1261
- }),
1262
- expected: %(
1263
- <<<ex:rei> <ex:prop> _:b0>> <ex:prop> "value2" .
1264
- ),
1265
- },
1266
- "node with recursive embedded subject": {
1267
- input: %({
1268
- "@id": {
1269
- "@id": {
1270
- "@id": "ex:rei",
1271
- "ex:prop": "value3"
1272
- },
1273
- "ex:prop": "value"
1274
- },
1275
- "ex:prop": "value2"
1276
- }),
1277
- expected: %(
1278
- <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
1279
- ),
1280
- },
1281
- "illegal node with subject having no property": {
1282
- input: %({
1283
- "@id": {
1284
- "@id": "ex:rei"
1285
- },
1286
- "ex:prop": "value3"
1287
- }),
1288
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1289
- },
1290
- "illegal node with subject having multiple properties": {
1291
- input: %({
1292
- "@id": {
1293
- "@id": "ex:rei",
1294
- "ex:prop": ["value1", "value2"]
1295
- },
1296
- "ex:prop": "value3"
1297
- }),
1298
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1299
- },
1300
- "illegal node with subject having multiple types": {
1301
- input: %({
1302
- "@id": {
1303
- "@id": "ex:rei",
1304
- "@type": ["ex:Type1", "ex:Type2"]
1305
- },
1306
- "ex:prop": "value3"
1307
- }),
1308
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1309
- },
1310
- "illegal node with subject having type and property": {
1311
- input: %({
1312
- "@id": {
1313
- "@id": "ex:rei",
1314
- "@type": "ex:Type",
1315
- "ex:prop": "value"
1316
- },
1317
- "ex:prop": "value2"
1318
- }),
1319
- exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
1320
- },
1321
- "node with embedded object": {
1322
- input: %({
1323
- "@id": "ex:subj",
1324
- "ex:value": {
1325
- "@id": {
1326
- "@id": "ex:rei",
1327
- "ex:prop": "value"
1328
- }
1329
- }
1330
- }),
1331
- expected: %(
1332
- <ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
1333
- ),
1334
- },
1335
- "node with embedded object having properties": {
1336
- input: %({
1337
- "@id": "ex:subj",
1338
- "ex:value": {
1339
- "@id": {
1340
- "@id": "ex:rei",
1341
- "ex:prop": "value"
1342
- },
1343
- "ex:prop": "value2"
1344
- }
1345
- }),
1346
- expected: %(
1347
- <ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
1348
- <<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
1349
- ),
1350
- },
1351
- "node with recursive embedded object": {
1352
- input: %({
1353
- "@id": "ex:subj",
1354
- "ex:value": {
1355
- "@id": {
1356
- "@id": {
1357
- "@id": "ex:rei",
1358
- "ex:prop": "value3"
1359
- },
1360
- "ex:prop": "value"
1361
- },
1362
- "ex:prop": "value2"
1363
- }
1364
- }),
1365
- expected: %(
1366
- <ex:subj> <ex:value> <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> .
1367
- <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
1368
- ),
1369
- },
1370
- }.each do |title, params|
1371
- context(title) do
1372
- it "Generates statements" do
1373
- output_graph = RDF::Graph.new {|g| g << RDF::NTriples::Reader.new(params[:expected], rdfstar: true)}
1374
- run_to_rdf params.merge(rdfstar: true, output: output_graph)
1375
- end if params[:expected]
1376
-
1377
- it "Exception" do
1378
- run_to_rdf params.merge(rdfstar: true)
1379
- end if params[:exception]
1380
- end
1381
- end
1382
- end
1383
-
1384
- context "exceptions" do
1385
- {
1386
- "Invalid subject" => {
1387
- input: %({
1388
- "@id": "http://example.com/a b",
1389
- "http://example.com/foo": "bar"
1390
- }),
1391
- output: %()
1392
- },
1393
- "Invalid predicate" => {
1394
- input: %({
1395
- "@id": "http://example.com/foo",
1396
- "http://example.com/a b": "bar"
1397
- }),
1398
- output: %()
1399
- },
1400
- "Invalid object" => {
1401
- input: %({
1402
- "@id": "http://example.com/foo",
1403
- "http://example.com/bar": {"@id": "http://example.com/baz z"}
1404
- }),
1405
- output: %()
1406
- },
1407
- "Invalid type" => {
1408
- input: %({
1409
- "@id": "http://example.com/foo",
1410
- "@type": ["http://example.com/bar", "relative"]
1411
- }),
1412
- output: %(<http://example.com/foo> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/bar> .)
1413
- },
1414
- "Invalid language" => {
1415
- input: %({
1416
- "@id": "http://example.com/foo",
1417
- "http://example.com/bar": {"@value": "bar", "@language": "a b"}
1418
- }),
1419
- output: %(),
1420
- write: "@language must be valid BCP47"
1421
- },
1422
- "Invalid datatype" => {
1423
- input: %({
1424
- "@id": "http://example.com/foo",
1425
- "http://example.com/bar": {"@value": "bar", "@type": "http://example.com/baz z"}
1426
- }),
1427
- exception: JSON::LD::JsonLdError::InvalidTypedValue
1428
- },
1429
- "Injected IRIs check" => {
1430
- input: %({
1431
- "@id": "http://foo/> <http://bar/> <http://baz> .\n<data:little> <data:bobby> <data:tables> .\n<data:in-ur-base",
1432
- "http://killin/#yer": "dudes"
1433
- }),
1434
- output: %(),
1435
- pending: "jruby"
1436
- },
1437
- }.each do |title, params|
1438
- it(title) do
1439
- pending params[:pending] if params[:pending] == RUBY_ENGINE
1440
- run_to_rdf params
1441
- end
1442
- end
1443
- end
1444
- end
1445
-
1446
- context "html" do
1447
- {
1448
- "Transforms embedded JSON-LD script element": {
1449
- input: %(
1450
- <html>
1451
- <head>
1452
- <script type="application/ld+json">
1453
- {
1454
- "@context": {
1455
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1456
- },
1457
- "foo": [{"@value": "bar"}]
1458
- }
1459
- </script>
1460
- </head>
1461
- </html>),
1462
- output: %([ <http://example.com/foo> ( "bar")] .)
1463
- },
1464
- "Transforms first script element with extractAllScripts: false": {
1465
- input: %(
1466
- <html>
1467
- <head>
1468
- <script type="application/ld+json">
1469
- {
1470
- "@context": {
1471
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1472
- },
1473
- "foo": [{"@value": "bar"}]
1474
- }
1475
- </script>
1476
- <script type="application/ld+json">
1477
- {
1478
- "@context": {"ex": "http://example.com/"},
1479
- "@graph": [
1480
- {"ex:foo": {"@value": "foo"}},
1481
- {"ex:bar": {"@value": "bar"}}
1482
- ]
1483
- }
1484
- </script>
1485
- </head>
1486
- </html>),
1487
- output: %([ <http://example.com/foo> ( "bar")] .),
1488
- extractAllScripts: false
1489
- },
1490
- "Transforms targeted script element": {
1491
- input: %(
1492
- <html>
1493
- <head>
1494
- <script id="first" type="application/ld+json">
1495
- {
1496
- "@context": {
1497
- "foo": {"@id": "http://example.com/foo", "@container": "@list"}
1498
- },
1499
- "foo": [{"@value": "bar"}]
1500
- }
1501
- </script>
1502
- <script id="second" type="application/ld+json">
1503
- {
1504
- "@context": {"ex": "http://example.com/"},
1505
- "@graph": [
1506
- {"ex:foo": {"@value": "foo"}},
1507
- {"ex:bar": {"@value": "bar"}}
1508
- ]
1509
- }
1510
- </script>
1511
- </head>
1512
- </html>),
1513
- output: %(
1514
- [ <http://example.com/foo> "foo"] .
1515
- [ <http://example.com/bar> "bar"] .
1516
- ),
1517
- base: "http://example.org/doc#second"
1518
- },
1519
- }.each do |title, params|
1520
- it(title) do
1521
- params[:input] = StringIO.new(params[:input])
1522
- params[:input].send(:define_singleton_method, :content_type) {"text/html"}
1523
- run_to_rdf params.merge(validate: true)
1524
- end
1525
- end
1526
- end
1527
-
1528
- def parse(input, **options)
1529
- graph = options[:graph] || RDF::Graph.new
1530
- options = {logger: logger, validate: true, canonicalize: false}.merge(options)
1531
- JSON::LD::API.toRdf(StringIO.new(input), rename_bnodes: false, **options) {|st| graph << st}
1532
- graph
1533
- end
1534
-
1535
- def run_to_rdf(params)
1536
- input, output = params[:input], params[:output]
1537
- graph = params[:graph] || RDF::Graph.new
1538
- input = StringIO.new(input) if input.is_a?(String)
1539
- pending params.fetch(:pending, "test implementation") unless input
1540
- if params[:exception]
1541
- expect {JSON::LD::API.toRdf(input, **params)}.to raise_error(params[:exception])
1542
- else
1543
- if params[:write]
1544
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.to write(params[:write]).to(:error)
1545
- else
1546
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.not_to write.to(:error)
1547
- end
1548
- expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input)
1549
- end
1550
- end
1551
- end