yaml-ld 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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