yaml-ld 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +1 -0
  3. data/README.md +150 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/lib/yaml_ld/api.rb +295 -0
  7. data/lib/yaml_ld/format.rb +56 -0
  8. data/lib/yaml_ld/reader.rb +40 -0
  9. data/lib/yaml_ld/version.rb +20 -0
  10. data/lib/yaml_ld/writer.rb +42 -0
  11. data/lib/yaml_ld.rb +37 -0
  12. data/spec/api_spec.rb +92 -0
  13. data/spec/compact_spec.rb +358 -0
  14. data/spec/expand_spec.rb +565 -0
  15. data/spec/flatten_spec.rb +225 -0
  16. data/spec/format_spec.rb +54 -0
  17. data/spec/frame_spec.rb +662 -0
  18. data/spec/from_rdf_spec.rb +730 -0
  19. data/spec/matchers.rb +22 -0
  20. data/spec/reader_spec.rb +138 -0
  21. data/spec/spec_helper.rb +265 -0
  22. data/spec/support/extensions.rb +44 -0
  23. data/spec/test-files/test-1-compacted.jsonld +10 -0
  24. data/spec/test-files/test-1-context.jsonld +7 -0
  25. data/spec/test-files/test-1-expanded.jsonld +5 -0
  26. data/spec/test-files/test-1-input.yamlld +8 -0
  27. data/spec/test-files/test-1-rdf.ttl +8 -0
  28. data/spec/test-files/test-2-compacted.jsonld +20 -0
  29. data/spec/test-files/test-2-context.jsonld +7 -0
  30. data/spec/test-files/test-2-expanded.jsonld +16 -0
  31. data/spec/test-files/test-2-input.yamlld +16 -0
  32. data/spec/test-files/test-2-rdf.ttl +14 -0
  33. data/spec/test-files/test-3-compacted.jsonld +11 -0
  34. data/spec/test-files/test-3-context.jsonld +8 -0
  35. data/spec/test-files/test-3-expanded.jsonld +10 -0
  36. data/spec/test-files/test-3-input.yamlld +13 -0
  37. data/spec/test-files/test-3-rdf.ttl +8 -0
  38. data/spec/test-files/test-4-compacted.jsonld +10 -0
  39. data/spec/test-files/test-4-context.jsonld +7 -0
  40. data/spec/test-files/test-4-expanded.jsonld +6 -0
  41. data/spec/test-files/test-4-input.yamlld +9 -0
  42. data/spec/test-files/test-4-rdf.ttl +5 -0
  43. data/spec/test-files/test-5-compacted.jsonld +13 -0
  44. data/spec/test-files/test-5-context.jsonld +7 -0
  45. data/spec/test-files/test-5-expanded.jsonld +9 -0
  46. data/spec/test-files/test-5-input.yamlld +10 -0
  47. data/spec/test-files/test-5-rdf.ttl +7 -0
  48. data/spec/test-files/test-6-compacted.jsonld +10 -0
  49. data/spec/test-files/test-6-context.jsonld +7 -0
  50. data/spec/test-files/test-6-expanded.jsonld +10 -0
  51. data/spec/test-files/test-6-input.yamlld +12 -0
  52. data/spec/test-files/test-6-rdf.ttl +6 -0
  53. data/spec/test-files/test-7-compacted.jsonld +23 -0
  54. data/spec/test-files/test-7-context.jsonld +4 -0
  55. data/spec/test-files/test-7-expanded.jsonld +20 -0
  56. data/spec/test-files/test-7-input.yamlld +16 -0
  57. data/spec/test-files/test-7-rdf.ttl +14 -0
  58. data/spec/test-files/test-8-compacted.jsonld +34 -0
  59. data/spec/test-files/test-8-context.jsonld +11 -0
  60. data/spec/test-files/test-8-expanded.jsonld +24 -0
  61. data/spec/test-files/test-8-frame.jsonld +18 -0
  62. data/spec/test-files/test-8-framed.jsonld +25 -0
  63. data/spec/test-files/test-8-input.yamlld +24 -0
  64. data/spec/test-files/test-8-rdf.ttl +15 -0
  65. data/spec/test-files/test-9-compacted.jsonld +20 -0
  66. data/spec/test-files/test-9-context.jsonld +13 -0
  67. data/spec/test-files/test-9-expanded.jsonld +14 -0
  68. data/spec/test-files/test-9-input.yamlld +16 -0
  69. data/spec/to_rdf_spec.rb +556 -0
  70. data/spec/writer_spec.rb +441 -0
  71. metadata +350 -0
data/lib/yaml_ld.rb ADDED
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.unshift(File.expand_path("../ld", __FILE__))
3
+ require 'rdf' # @see https://rubygems.org/gems/rdf
4
+ require 'json/ld'
5
+ require 'psych'
6
+ require 'yaml_ld/format'
7
+
8
+ module YAML_LD
9
+ ##
10
+ # **`YAML_LD`** is a YAML-LD extension for RDF.rb.
11
+ #
12
+ # @example Requiring the `YAML_LD` module
13
+ # require 'yaml_ld'
14
+ #
15
+ # @example Parsing RDF statements from a YAML-LD file
16
+ # JSON::LD::Reader.open("etc/foaf.YAML_LD") do |reader|
17
+ # reader.each_statement do |statement|
18
+ # puts statement.inspect
19
+ # end
20
+ # end
21
+ #
22
+ # @see https://rubygems.org/gems/rdf
23
+ # @see http://www.w3.org/TR/REC-rdf-syntax/
24
+ #
25
+ # @note Classes and module use `YAML_LD` instead of `YAML_LD`, as `Psych` squats on the `YAML` module.
26
+ #
27
+ # @author [Gregg Kellogg](http://greggkellogg.net/)
28
+
29
+ autoload :API, 'yaml_ld/api'
30
+ autoload :Reader, 'yaml_ld/reader'
31
+ autoload :VERSION, 'yaml_ld/version'
32
+ autoload :Writer, 'yaml_ld/writer'
33
+
34
+ # YAML-LD profiles
35
+ YAML_LD_NS = "http://www.w3.org/ns/yaml-ld#"
36
+ PROFILES = %w(extended).map {|p| YAML_LD_NS + p}.freeze
37
+ end
data/spec/api_spec.rb ADDED
@@ -0,0 +1,92 @@
1
+
2
+ # coding: utf-8
3
+ require_relative 'spec_helper'
4
+
5
+ describe YAML_LD::API do
6
+ let(:logger) {RDF::Spec.logger}
7
+ before {JSON::LD::Context::PRELOADED.clear}
8
+
9
+ context "Test Files" do
10
+ %i(psych).each do |adapter|
11
+ Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'test-files/*-input.*'))) do |filename|
12
+ test = File.basename(filename).sub(/-input\..*$/, '')
13
+ frame = filename.sub(/-input\..*$/, '-frame.jsonld')
14
+ framed = filename.sub(/-input\..*$/, '-framed.jsonld')
15
+ compacted = filename.sub(/-input\..*$/, '-compacted.jsonld')
16
+ context = filename.sub(/-input\..*$/, '-context.jsonld')
17
+ expanded = filename.sub(/-input\..*$/, '-expanded.jsonld')
18
+ expanded_yaml = filename.sub(/-input\..*$/, '-expanded.yamlld')
19
+ ttl = filename.sub(/-input\..*$/, '-rdf.ttl')
20
+
21
+ context test do
22
+ around do |example|
23
+ @file = File.open(filename)
24
+ case filename
25
+ when /\.yamlld$/
26
+ @file.define_singleton_method(:content_type) {'application/ld+yaml'}
27
+ when /.jsonld$/
28
+ @file.define_singleton_method(:content_type) {'application/ld+json'}
29
+ end
30
+ if context
31
+ @ctx_io = File.open(context)
32
+ case context
33
+ when /\.yamlld$/
34
+ @ctx_io.define_singleton_method(:content_type) {'application/ld+yaml'}
35
+ when /.jsonld$/
36
+ @ctx_io.define_singleton_method(:content_type) {'application/ld+json'}
37
+ end
38
+ end
39
+ example.run
40
+ @file.close
41
+ @ctx_io.close if @ctx_io
42
+ end
43
+
44
+ if File.exist?(expanded)
45
+ it "expands" do
46
+ options = {logger: logger, adapter: adapter}
47
+ options[:expandContext] = @ctx_io if context
48
+ yaml = described_class.expand(@file, **options)
49
+ expect(yaml).to be_a(String)
50
+ parsed_json = JSON.parse(File.read(expanded))
51
+ expect(yaml).to produce_yamlld(parsed_json, logger)
52
+ end
53
+ end
54
+
55
+ if File.exist?(expanded_yaml)
56
+ it "expands to YAML" do
57
+ options = {logger: logger, adapter: adapter}
58
+ options[:expandContext] = @ctx_io if context
59
+ yaml = described_class.expand(@file, **options)
60
+ expect(yaml).to be_a(String)
61
+ expect(yaml).to produce_yamlld(YAML.load_file(expanded_yaml), logger)
62
+ end
63
+ end
64
+
65
+ if File.exist?(compacted) && File.exist?(context)
66
+ it "compacts" do
67
+ yaml = described_class.compact(@file, @ctx_io, adapter: adapter, logger: logger)
68
+ expect(yaml).to be_a(String)
69
+ parsed_json = JSON.parse(File.read(compacted))
70
+ expect(yaml).to produce_yamlld(parsed_json, logger)
71
+ end
72
+ end
73
+
74
+ if File.exist?(framed) && File.exist?(frame)
75
+ it "frames" do
76
+ File.open(frame) do |frame_io|
77
+ yaml = described_class.frame(@file, frame_io, adapter: adapter, logger: logger)
78
+ expect(yaml).to be_a(String)
79
+ parsed_json = JSON.parse(File.read(framed))
80
+ expect(yaml).to produce_yamlld(parsed_json, logger)
81
+ end
82
+ end
83
+ end
84
+
85
+ it "toRdf" do
86
+ expect(RDF::Repository.load(filename, format: :yamlld, adapter: adapter, logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger)
87
+ end if File.exist?(ttl)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,358 @@
1
+ # coding: utf-8
2
+ require_relative 'spec_helper'
3
+
4
+ describe YAML_LD::API do
5
+ let(:logger) {RDF::Spec.logger}
6
+
7
+ describe ".compact" do
8
+ {
9
+ "prefix" => {
10
+ input: %(---
11
+ "@id": http://example.com/a
12
+ http://example.com/b:
13
+ "@id": http://example.com/c
14
+ ),
15
+ context: %({"ex": "http://example.com/"}),
16
+ output: %(%YAML 1.2\n---
17
+ "@context":
18
+ ex: http://example.com/
19
+ "@id": ex:a
20
+ ex:b:
21
+ "@id": ex:c
22
+ )
23
+ },
24
+ "term" => {
25
+ input: %(---
26
+ "@id": http://example.com/a
27
+ http://example.com/b:
28
+ "@id": http://example.com/c
29
+ ),
30
+ context: %({"b": "http://example.com/b"}),
31
+ output: %(%YAML 1.2\n---
32
+ "@context":
33
+ b: http://example.com/b
34
+ "@id": http://example.com/a
35
+ b:
36
+ "@id": http://example.com/c
37
+ )
38
+ },
39
+ "integer value" => {
40
+ input: %(---
41
+ "@id": http://example.com/a
42
+ http://example.com/b:
43
+ "@value": 1
44
+ ),
45
+ context: %({"b": "http://example.com/b"}),
46
+ output: %(%YAML 1.2\n---
47
+ "@context":
48
+ b: http://example.com/b
49
+ "@id": http://example.com/a
50
+ b: 1
51
+ )
52
+ },
53
+ "boolean value" => {
54
+ input: %(---
55
+ "@id": http://example.com/a
56
+ http://example.com/b:
57
+ "@value": true
58
+ ),
59
+ context: %({"b": "http://example.com/b"}),
60
+ output: %(%YAML 1.2\n---
61
+ "@context":
62
+ b: http://example.com/b
63
+ "@id": http://example.com/a
64
+ b: true
65
+ )
66
+ },
67
+ "@id" => {
68
+ input: %(---
69
+ "@id": http://example.org/test#example
70
+ ),
71
+ context: {},
72
+ output: %{%YAML 1.2
73
+ --- {}
74
+ }
75
+ },
76
+ "@id coercion" => {
77
+ input: %({
78
+ "@id": "http://example.com/a",
79
+ "http://example.com/b": {"@id": "http://example.com/c"}
80
+ }),
81
+ context: %({"b": {"@id": "http://example.com/b", "@type": "@id"}}),
82
+ output: %(%YAML 1.2\n---
83
+ "@context":
84
+ b:
85
+ "@id": http://example.com/b
86
+ "@type": "@id"
87
+ "@id": http://example.com/a
88
+ b: http://example.com/c
89
+ )
90
+ },
91
+ "xsd:date coercion" => {
92
+ input: %(---
93
+ http://example.com/b:
94
+ "@value": '2012-01-04'
95
+ "@type": http://www.w3.org/2001/XMLSchema#date
96
+ ),
97
+ context: %({
98
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
99
+ "b": {"@id": "http://example.com/b", "@type": "xsd:date"}
100
+ }),
101
+ output: %(%YAML 1.2\n---
102
+ "@context":
103
+ xsd: http://www.w3.org/2001/XMLSchema#
104
+ b:
105
+ "@id": http://example.com/b
106
+ "@type": xsd:date
107
+ b: '2012-01-04'
108
+ )
109
+ },
110
+ "default language" => {
111
+ input: %(---
112
+ http://example.com/term:
113
+ - v5
114
+ - "@value": plain literal
115
+ ),
116
+ context: %({
117
+ "term5": {"@id": "http://example.com/term", "@language": null},
118
+ "@language": "de"
119
+ }),
120
+ output: %(%YAML 1.2\n---
121
+ "@context":
122
+ term5:
123
+ "@id": http://example.com/term
124
+ "@language":
125
+ "@language": de
126
+ term5:
127
+ - v5
128
+ - plain literal
129
+ )
130
+ },
131
+ "default direction" => {
132
+ input: %(---
133
+ http://example.com/term:
134
+ - v5
135
+ - "@value": plain literal
136
+ ),
137
+ context: %({
138
+ "term5": {"@id": "http://example.com/term", "@direction": null},
139
+ "@direction": "ltr"
140
+ }),
141
+ output: %(%YAML 1.2\n---
142
+ "@context":
143
+ term5:
144
+ "@id": http://example.com/term
145
+ "@direction":
146
+ "@direction": ltr
147
+ term5:
148
+ - v5
149
+ - plain literal
150
+ )
151
+ },
152
+ }.each_pair do |title, params|
153
+ it(title) {run_compact(params)}
154
+ end
155
+
156
+ context "with @type: @json" do
157
+ {
158
+ "true": {
159
+ output: %(%YAML 1.2\n---
160
+ "@context":
161
+ "@version": 1.1
162
+ e:
163
+ "@id": http://example.org/vocab#bool
164
+ "@type": "@json"
165
+ e: true
166
+ ),
167
+ input:%(
168
+ - http://example.org/vocab#bool:
169
+ - "@value": true
170
+ "@type": "@json"
171
+ ),
172
+ },
173
+ "false": {
174
+ output: %(%YAML 1.2\n---
175
+ "@context":
176
+ "@version": 1.1
177
+ e:
178
+ "@id": http://example.org/vocab#bool
179
+ "@type": "@json"
180
+ e: false
181
+ ),
182
+ input:%(
183
+ - http://example.org/vocab#bool:
184
+ - "@value": false
185
+ "@type": "@json"
186
+ )
187
+ },
188
+ "double": {
189
+ output: %(%YAML 1.2\n---
190
+ "@context":
191
+ "@version": 1.1
192
+ e:
193
+ "@id": http://example.org/vocab#double
194
+ "@type": "@json"
195
+ e: 1.23
196
+ ),
197
+ input:%(
198
+ - http://example.org/vocab#double:
199
+ - "@value": 1.23
200
+ "@type": "@json"
201
+ )
202
+ },
203
+ "double-zero": {
204
+ output: %(%YAML 1.2\n---
205
+ "@context":
206
+ "@version": 1.1
207
+ e:
208
+ "@id": http://example.org/vocab#double
209
+ "@type": "@json"
210
+ e: 0.0e0
211
+ ),
212
+ input:%(
213
+ - http://example.org/vocab#double:
214
+ - "@value": 0.0e0
215
+ "@type": "@json"
216
+ )
217
+ },
218
+ "integer": {
219
+ output: %(%YAML 1.2\n---
220
+ "@context":
221
+ "@version": 1.1
222
+ e:
223
+ "@id": http://example.org/vocab#integer
224
+ "@type": "@json"
225
+ e: 123
226
+ ),
227
+ input:%(
228
+ - http://example.org/vocab#integer:
229
+ - "@value": 123
230
+ "@type": "@json"
231
+ )
232
+ },
233
+ "string": {
234
+ output: %(%YAML 1.2\n---
235
+ "@context":
236
+ "@version": 1.1
237
+ e:
238
+ "@id": http://example.org/vocab#string
239
+ "@type": "@json"
240
+ e: string
241
+ ),
242
+ input:%(
243
+ - http://example.org/vocab#string:
244
+ - "@value": string
245
+ "@type": "@json"
246
+ )
247
+ },
248
+ "null": {
249
+ output: %(%YAML 1.2\n---
250
+ "@context":
251
+ "@version": 1.1
252
+ e:
253
+ "@id": http://example.org/vocab#null
254
+ "@type": "@json"
255
+ e:
256
+ ),
257
+ input:%(
258
+ - http://example.org/vocab#null:
259
+ - "@value": null
260
+ "@type": "@json"
261
+ )
262
+ },
263
+ "object": {
264
+ output: %(%YAML 1.2\n---
265
+ "@context":
266
+ "@version": 1.1
267
+ e:
268
+ "@id": http://example.org/vocab#object
269
+ "@type": "@json"
270
+ e:
271
+ foo: bar
272
+ ),
273
+ input:%(
274
+ - http://example.org/vocab#object:
275
+ - "@value":
276
+ foo: bar
277
+ "@type": "@json"
278
+ )
279
+ },
280
+ "array": {
281
+ output: %(%YAML 1.2\n---
282
+ "@context":
283
+ "@version": 1.1
284
+ e:
285
+ "@id": http://example.org/vocab#object
286
+ "@type": "@json"
287
+ e:
288
+ - foo
289
+ - bar
290
+ ),
291
+ input:%(
292
+ - http://example.org/vocab#object:
293
+ - "@value": [foo, bar]
294
+ "@type": "@json"
295
+ )
296
+ },
297
+ "Already expanded object": {
298
+ output: %(%YAML 1.2\n---
299
+ "@context":
300
+ "@version": 1.1
301
+ http://example.org/vocab#object:
302
+ "@value":
303
+ foo: bar
304
+ "@type": "@json"
305
+ ),
306
+ input:%(
307
+ - http://example.org/vocab#object:
308
+ - "@value": {foo: bar}
309
+ "@type": "@json"
310
+ )
311
+ },
312
+ "Already expanded object with aliased keys": {
313
+ output: %(%YAML 1.2\n---
314
+ "@context":
315
+ "@version": 1.1
316
+ value: "@value"
317
+ type: "@type"
318
+ json: "@json"
319
+ http://example.org/vocab#object:
320
+ value:
321
+ foo: bar
322
+ type: json
323
+ ),
324
+ input:%(
325
+ - http://example.org/vocab#object:
326
+ - "@value": {foo: bar}
327
+ "@type": "@json"
328
+ )
329
+ },
330
+ }.each do |title, params|
331
+ it(title) {run_compact(processingMode: 'json-ld-1.1', **params)}
332
+ end
333
+ end
334
+ end
335
+
336
+ def run_compact(params)
337
+ input, output, context = params[:input], params[:output], params[:context]
338
+ params[:base] ||= nil
339
+ context ||= output # Since it will have the context
340
+ input = StringIO.new(input.unindent) if input.is_a?(String)
341
+ input.define_singleton_method(:content_type) {'application/ld+yaml'}
342
+ context = Psych.safe_load(context.unindent, aliases: true) if context.is_a?(String)
343
+ context = context['@context'] if context.key?('@context')
344
+ pending params.fetch(:pending, "test implementation") unless input
345
+ if params[:exception]
346
+ expect {YAML_LD::API.compact(input, context, logger: logger, **params)}.to raise_error(params[:exception])
347
+ else
348
+ yaml = nil
349
+ if params[:write]
350
+ expect{yaml = YAML_LD::API.compact(input, context, logger: logger, **params)}.to write(params[:write]).to(:error)
351
+ else
352
+ expect{yaml = YAML_LD::API.compact(input, context, logger: logger, **params)}.not_to write.to(:error)
353
+ end
354
+
355
+ expect(yaml.strip).to eq output.unindent.strip
356
+ end
357
+ end
358
+ end