json-ld 0.9.1 → 1.0.0

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 (45) hide show
  1. data/{README.markdown → README.md} +15 -3
  2. data/VERSION +1 -1
  3. data/lib/json/ld.rb +50 -87
  4. data/lib/json/ld/api.rb +85 -96
  5. data/lib/json/ld/compact.rb +103 -170
  6. data/lib/json/ld/context.rb +1137 -0
  7. data/lib/json/ld/expand.rb +212 -171
  8. data/lib/json/ld/extensions.rb +17 -1
  9. data/lib/json/ld/flatten.rb +145 -78
  10. data/lib/json/ld/frame.rb +1 -1
  11. data/lib/json/ld/from_rdf.rb +73 -103
  12. data/lib/json/ld/reader.rb +3 -1
  13. data/lib/json/ld/resource.rb +3 -3
  14. data/lib/json/ld/to_rdf.rb +98 -109
  15. data/lib/json/ld/utils.rb +54 -4
  16. data/lib/json/ld/writer.rb +5 -5
  17. data/spec/api_spec.rb +3 -28
  18. data/spec/compact_spec.rb +76 -113
  19. data/spec/{evaluation_context_spec.rb → context_spec.rb} +307 -563
  20. data/spec/expand_spec.rb +163 -187
  21. data/spec/flatten_spec.rb +119 -114
  22. data/spec/frame_spec.rb +5 -5
  23. data/spec/from_rdf_spec.rb +44 -24
  24. data/spec/suite_compact_spec.rb +11 -8
  25. data/spec/suite_error_expand_spec.rb +23 -0
  26. data/spec/suite_expand_spec.rb +3 -7
  27. data/spec/suite_flatten_spec.rb +3 -3
  28. data/spec/suite_frame_spec.rb +6 -6
  29. data/spec/suite_from_rdf_spec.rb +3 -3
  30. data/spec/suite_helper.rb +13 -6
  31. data/spec/suite_to_rdf_spec.rb +16 -10
  32. data/spec/test-files/test-1-rdf.ttl +4 -3
  33. data/spec/test-files/test-3-rdf.ttl +2 -1
  34. data/spec/test-files/test-4-compacted.json +1 -1
  35. data/spec/test-files/test-5-rdf.ttl +3 -2
  36. data/spec/test-files/test-6-rdf.ttl +3 -2
  37. data/spec/test-files/test-7-compacted.json +3 -3
  38. data/spec/test-files/test-7-expanded.json +3 -3
  39. data/spec/test-files/test-7-rdf.ttl +7 -6
  40. data/spec/test-files/test-9-compacted.json +1 -1
  41. data/spec/to_rdf_spec.rb +67 -75
  42. data/spec/writer_spec.rb +2 -0
  43. metadata +36 -24
  44. checksums.yaml +0 -15
  45. data/lib/json/ld/evaluation_context.rb +0 -984
@@ -5,119 +5,14 @@ require 'spec_helper'
5
5
  describe JSON::LD::API do
6
6
  before(:each) { @debug = []}
7
7
 
8
- describe "#generate_node_map" do
9
- {
10
- "single object" => {
11
- :input => {"@id" => "http://example.com", "@type" => RDF::RDFS.Resource.to_s},
12
- :subjects => %w(http://example.com),
13
- :output => {
14
- "http://example.com" => {
15
- "@id" => "http://example.com", "@type" => [RDF::RDFS.Resource.to_s]
16
- }
17
- }
18
- },
19
- "embedded object" => {
20
- :input => {
21
- "@context" => {"foaf" => RDF::FOAF.to_s},
22
- "@id" => "http://greggkellogg.net/foaf",
23
- "@type" => ["foaf:PersonalProfile"],
24
- "foaf:primaryTopic" => [{
25
- "@id" => "http://greggkellogg.net/foaf#me",
26
- "@type" => ["foaf:Person"]
27
- }]
28
- },
29
- :subjects => %w(http://greggkellogg.net/foaf http://greggkellogg.net/foaf#me),
30
- :output => {
31
- "http://greggkellogg.net/foaf" => {
32
- "@id" => "http://greggkellogg.net/foaf",
33
- "@type" => [RDF::FOAF.PersonalProfile.to_s],
34
- RDF::FOAF.primaryTopic.to_s => [{"@id" => "http://greggkellogg.net/foaf#me"}]
35
- },
36
- "http://greggkellogg.net/foaf#me" => {
37
- "@id" => "http://greggkellogg.net/foaf#me",
38
- "@type" => [RDF::FOAF.Person.to_s]
39
- }
40
- }
41
- },
42
- "embedded anon" => {
43
- :input => {
44
- "@context" => {"foaf" => RDF::FOAF.to_s},
45
- "@id" => "http://greggkellogg.net/foaf",
46
- "@type" => "foaf:PersonalProfile",
47
- "foaf:primaryTopic" => {
48
- "@type" => "foaf:Person"
49
- }
50
- },
51
- :subjects => %w(http://greggkellogg.net/foaf _:t0),
52
- :output => {
53
- "_:t0" => {
54
- "@id" => "_:t0",
55
- "@type" => [RDF::FOAF.Person.to_s]
56
- },
57
- "http://greggkellogg.net/foaf" => {
58
- "@id" => "http://greggkellogg.net/foaf",
59
- "@type" => [RDF::FOAF.PersonalProfile.to_s],
60
- RDF::FOAF.primaryTopic.to_s => [{"@id" => "_:t0"}]
61
- },
62
- }
63
- },
64
- "anon in list" => {
65
- :input => [{
66
- "@id" => "_:a",
67
- "http://example.com/list" => [{"@list" => [{"@id" => "_:b"}]}]
68
- }, {
69
- "@id" => "_:b",
70
- "http://example.com/name" => "foo"
71
- }],
72
- :subjects => %w(_:t0 _:t1),
73
- :output => {
74
- "_:t0" => {
75
- "@id" => "_:t0",
76
- "http://example.com/list" => [
77
- {
78
- "@list" => [
79
- {
80
- "@id" => "_:t1"
81
- }
82
- ]
83
- }
84
- ]
85
- },
86
- "_:t1" => {
87
- "@id" => "_:t1",
88
- "http://example.com/name" => [
89
- {
90
- "@value" => "foo"
91
- }
92
- ]
93
- }
94
- }
95
- }
96
- }.each do |title, params|
97
- it title do
98
- @debug = []
99
- @node_map = Hash.ordered
100
- graph = params[:graph] || '@merged'
101
- jld = nil
102
- expanded_value = JSON::LD::API.expand(params[:input])
103
- JSON::LD::API.new(expanded_value, nil, :debug => @debug) do |api|
104
- api.generate_node_map(expanded_value,
105
- @node_map,
106
- graph)
107
- end
108
- @node_map.keys.should produce([graph], @debug)
109
- subjects = @node_map[graph]
110
- subjects.keys.should produce(params[:subjects], @debug)
111
- subjects.should produce(params[:output], @debug)
112
- end
113
- end
114
- end
115
-
116
8
  describe ".flatten" do
117
9
  {
118
10
  "single object" => {
119
11
  :input => {"@id" => "http://example.com", "@type" => RDF::RDFS.Resource.to_s},
120
- :output => [{"@id" => "http://example.com", "@type" => [RDF::RDFS.Resource.to_s]}]
12
+ :output => [
13
+ {"@id" => "http://example.com", "@type" => [RDF::RDFS.Resource.to_s]},
14
+ {"@id" => RDF::RDFS.Resource.to_s}
15
+ ]
121
16
  },
122
17
  "embedded object" => {
123
18
  :input => {
@@ -140,7 +35,9 @@ describe JSON::LD::API do
140
35
  {
141
36
  "@id" => "http://greggkellogg.net/foaf#me",
142
37
  "@type" => [RDF::FOAF.Person.to_s]
143
- }
38
+ },
39
+ {"@id" => RDF::FOAF.Person.to_s},
40
+ {"@id" => RDF::FOAF.PersonalProfile.to_s},
144
41
  ]
145
42
  },
146
43
  "embedded anon" => {
@@ -156,21 +53,129 @@ describe JSON::LD::API do
156
53
  },
157
54
  :output => [
158
55
  {
159
- "@id" => "_:t0",
56
+ "@id" => "_:b0",
160
57
  "@type" => [RDF::FOAF.Person.to_s]
161
58
  },
162
59
  {
163
60
  "@id" => "http://greggkellogg.net/foaf",
164
61
  "@type" => [RDF::FOAF.PersonalProfile.to_s],
165
- RDF::FOAF.primaryTopic.to_s => [{"@id" => "_:t0"}]
62
+ RDF::FOAF.primaryTopic.to_s => [{"@id" => "_:b0"}]
166
63
  },
64
+ {"@id" => RDF::FOAF.Person.to_s},
65
+ {"@id" => RDF::FOAF.PersonalProfile.to_s},
167
66
  ]
67
+ },
68
+ "reverse properties" => {
69
+ :input => ::JSON.parse(%([
70
+ {
71
+ "@id": "http://example.com/people/markus",
72
+ "@reverse": {
73
+ "http://xmlns.com/foaf/0.1/knows": [
74
+ {
75
+ "@id": "http://example.com/people/dave"
76
+ },
77
+ {
78
+ "@id": "http://example.com/people/gregg"
79
+ }
80
+ ]
81
+ },
82
+ "http://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ]
83
+ }
84
+ ])),
85
+ :output => ::JSON.parse(%([
86
+ {
87
+ "@id": "http://example.com/people/dave",
88
+ "http://xmlns.com/foaf/0.1/knows": [
89
+ {
90
+ "@id": "http://example.com/people/markus"
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "@id": "http://example.com/people/gregg",
96
+ "http://xmlns.com/foaf/0.1/knows": [
97
+ {
98
+ "@id": "http://example.com/people/markus"
99
+ }
100
+ ]
101
+ },
102
+ {
103
+ "@id": "http://example.com/people/markus",
104
+ "http://xmlns.com/foaf/0.1/name": [
105
+ {
106
+ "@value": "Markus Lanthaler"
107
+ }
108
+ ]
109
+ }
110
+ ]))
111
+ },
112
+ "Simple named graph (Wikidata)" => {
113
+ :input => ::JSON.parse(%q({
114
+ "@context": {
115
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
116
+ "ex": "http://example.org/",
117
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
118
+ "ex:locatedIn": {"@type": "@id"},
119
+ "ex:hasPopulaton": {"@type": "xsd:integer"},
120
+ "ex:hasReference": {"@type": "@id"}
121
+ },
122
+ "@graph": [
123
+ {
124
+ "@id": "http://example.org/ParisFact1",
125
+ "@type": "rdf:Graph",
126
+ "@graph": {
127
+ "@id": "http://example.org/location/Paris#this",
128
+ "ex:locatedIn": "http://example.org/location/France#this"
129
+ },
130
+ "ex:hasReference": ["http://www.britannica.com/", "http://www.wikipedia.org/", "http://www.brockhaus.de/"]
131
+ },
132
+ {
133
+ "@id": "http://example.org/ParisFact2",
134
+ "@type": "rdf:Graph",
135
+ "@graph": {
136
+ "@id": "http://example.org/location/Paris#this",
137
+ "ex:hasPopulation": 7000000
138
+ },
139
+ "ex:hasReference": "http://www.wikipedia.org/"
140
+ }
141
+ ]
142
+ })),
143
+ :output => ::JSON.parse(%q([{
144
+ "@id": "http://example.org/ParisFact1",
145
+ "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"],
146
+ "http://example.org/hasReference": [
147
+ {"@id": "http://www.britannica.com/"},
148
+ {"@id": "http://www.wikipedia.org/"},
149
+ {"@id": "http://www.brockhaus.de/"}
150
+ ],
151
+ "@graph": [{
152
+ "@id": "http://example.org/location/France#this"
153
+ }, {
154
+ "@id": "http://example.org/location/Paris#this",
155
+ "http://example.org/locatedIn": [{"@id": "http://example.org/location/France#this"}]
156
+ }]
157
+ }, {
158
+ "@id": "http://example.org/ParisFact2",
159
+ "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"],
160
+ "http://example.org/hasReference": [{"@id": "http://www.wikipedia.org/"}],
161
+ "@graph": [{
162
+ "@id": "http://example.org/location/Paris#this",
163
+ "http://example.org/hasPopulation": [{"@value": 7000000}]
164
+ }]
165
+ }, {
166
+ "@id": "http://www.britannica.com/"
167
+ }, {
168
+ "@id": "http://www.brockhaus.de/"
169
+ }, {
170
+ "@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"
171
+ }, {
172
+ "@id": "http://www.wikipedia.org/"
173
+ }])),
168
174
  }
169
175
  }.each do |title, params|
170
176
  it title do
171
177
  @debug = []
172
- graph = params[:graph] || '@merged'
173
- jld = JSON::LD::API.flatten(params[:input], graph, nil, nil, :debug => @debug)
178
+ jld = JSON::LD::API.flatten(params[:input], nil, :debug => @debug)
174
179
  jld.should produce(params[:output], @debug)
175
180
  end
176
181
  end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe JSON::LD::API do
6
6
  before(:each) { @debug = []}
7
7
 
8
- describe ".frame", :pending => "Must investigate" do
8
+ describe ".frame" do
9
9
  {
10
10
  "frame with @type matches subject with @type" => {
11
11
  :frame => {
@@ -477,15 +477,15 @@ describe JSON::LD::API do
477
477
  },
478
478
  "@graph" => [
479
479
  {
480
- "@id" => "_:t0",
480
+ "@id" => "_:b0",
481
481
  "@type" => "mf:Manifest",
482
482
  "comment" => "Positive processor tests",
483
483
  "entries" => [
484
484
  {
485
- "@id" => "_:t1",
485
+ "@id" => "_:b1",
486
486
  "@type" => "mf:ManifestEntry",
487
487
  "action" => {
488
- "@id" => "_:t2",
488
+ "@id" => "_:b2",
489
489
  "@type" => "mq:QueryTest",
490
490
  "data" => "http://www.w3.org/TR/microdata-rdf/tests/0001.html",
491
491
  "query" => "http://www.w3.org/TR/microdata-rdf/tests/0001.ttl"
@@ -503,7 +503,7 @@ describe JSON::LD::API do
503
503
  it title do
504
504
  @debug = []
505
505
  begin
506
- jld = JSON::LD::API.frame(params[:input], params[:frame], nil, :debug => @debug)
506
+ jld = JSON::LD::API.frame(params[:input], params[:frame], :debug => @debug)
507
507
  jld.should produce(params[:output], @debug)
508
508
  rescue JSON::LD::ProcessingError, JSON::LD::InvalidContext, JSON::LD::InvalidFrame => e
509
509
  fail("#{e.class}: #{e.message}\n" +
@@ -12,7 +12,10 @@ describe JSON::LD::API do
12
12
  {
13
13
  '@id' => "http://a/b",
14
14
  "http://a/c" => [{"@id" => "http://a/d"}]
15
- }], @debug)
15
+ }, {
16
+ '@id' => 'http://a/d'
17
+ }
18
+ ], @debug)
16
19
  end
17
20
 
18
21
  it "should generate object list" do
@@ -24,7 +27,10 @@ describe JSON::LD::API do
24
27
  {"@id" => "http://example.com/d"},
25
28
  {"@id" => "http://example.com/e"}
26
29
  ]
27
- }], @debug)
30
+ },
31
+ {"@id" => "http://example.com/d"},
32
+ {"@id" => "http://example.com/e"}
33
+ ], @debug)
28
34
  end
29
35
 
30
36
  it "should generate property list" do
@@ -34,7 +40,10 @@ describe JSON::LD::API do
34
40
  '@id' => "http://example.com/b",
35
41
  "http://example.com/c" => [{"@id" => "http://example.com/d"}],
36
42
  "http://example.com/e" => [{"@id" => "http://example.com/f"}]
37
- }], @debug)
43
+ },
44
+ {"@id" => "http://example.com/d"},
45
+ {"@id" => "http://example.com/f"}
46
+ ], @debug)
38
47
  end
39
48
 
40
49
  it "serializes multiple subjects" do
@@ -46,8 +55,9 @@ describe JSON::LD::API do
46
55
  )
47
56
  serialize(input).
48
57
  should produce([
58
+ {'@id' => "http://www.w3.org/2006/03/test-description#TestCase"},
49
59
  {'@id' => "test-cases/0001", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]},
50
- {'@id' => "test-cases/0002", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]}
60
+ {'@id' => "test-cases/0002", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]},
51
61
  ], @debug)
52
62
  end
53
63
  end
@@ -56,10 +66,12 @@ describe JSON::LD::API do
56
66
  context "coercion" do
57
67
  it "typed literal" do
58
68
  input = %(@prefix ex: <http://example.com/> . ex:a ex:b "foo"^^ex:d .)
59
- serialize(input).should produce([{
60
- '@id' => "http://example.com/a",
61
- "http://example.com/b" => [{"@value" => "foo", "@type" => "http://example.com/d"}]
62
- }], @debug)
69
+ serialize(input).should produce([
70
+ {
71
+ '@id' => "http://example.com/a",
72
+ "http://example.com/b" => [{"@value" => "foo", "@type" => "http://example.com/d"}]
73
+ }
74
+ ], @debug)
63
75
  end
64
76
 
65
77
  it "integer" do
@@ -154,10 +166,13 @@ describe JSON::LD::API do
154
166
  context "anons" do
155
167
  it "should generate bare anon" do
156
168
  input = %(@prefix : <http://example.com/> . _:a :a :b .)
157
- serialize(input).should produce([{
169
+ serialize(input).should produce([
170
+ {
158
171
  "@id" => "_:a",
159
172
  "http://example.com/a" => [{"@id" => "http://example.com/b"}]
160
- }], @debug)
173
+ },
174
+ {"@id" => "http://example.com/b"}
175
+ ], @debug)
161
176
  end
162
177
 
163
178
  it "should generate anon as object" do
@@ -171,6 +186,7 @@ describe JSON::LD::API do
171
186
  "@id" => "http://example.com/a",
172
187
  "http://example.com/b" => [{"@id" => "_:a"}]
173
188
  },
189
+ {"@id" => "http://example.com/d"},
174
190
  ], @debug)
175
191
  end
176
192
  end
@@ -202,7 +218,7 @@ describe JSON::LD::API do
202
218
  {"@id" => "http://example.com/c"}
203
219
  ]
204
220
  }]
205
- }], @debug)
221
+ }, {"@id" => "http://example.com/c"}], @debug)
206
222
  end
207
223
 
208
224
  it "should generate empty list" do
@@ -249,8 +265,8 @@ describe JSON::LD::API do
249
265
  "@graph" => [{
250
266
  "@id" => "http://example.com/a",
251
267
  "http://example.com/b" => [{"@id" => "http://example.com/c"}]
252
- }]
253
- }
268
+ }, {"@id" => "http://example.com/c"}]
269
+ },
254
270
  ]
255
271
  },
256
272
  "with properties" => {
@@ -264,9 +280,10 @@ describe JSON::LD::API do
264
280
  "@graph" => [{
265
281
  "@id" => "http://example.com/a",
266
282
  "http://example.com/b" => [{"@id" => "http://example.com/c"}]
267
- }],
283
+ }, {"@id" => "http://example.com/c"}],
268
284
  "http://example.com/d" => [{"@id" => "http://example.com/e"}]
269
- }
285
+ },
286
+ {"@id" => "http://example.com/e"}
270
287
  ]
271
288
  },
272
289
  "with lists" => {
@@ -284,9 +301,10 @@ describe JSON::LD::API do
284
301
  "@graph" => [{
285
302
  "@id" => "http://example.com/a",
286
303
  "http://example.com/b" => [{"@list" => [{"@id" => "http://example.com/c"}]}]
287
- }],
304
+ }, {"@id" => "http://example.com/c"}],
288
305
  "http://example.com/d" => [{"@list" => [{"@id" => "http://example.com/e"}]}]
289
- }
306
+ },
307
+ {"@id" => "http://example.com/e"}
290
308
  ]
291
309
  },
292
310
  "Two Graphs with same subject and lists" => {
@@ -307,7 +325,8 @@ describe JSON::LD::API do
307
325
  "http://example.com/b" => [{
308
326
  "@list" => [{"@id" => "http://example.com/c"}]
309
327
  }]
310
- }
328
+ },
329
+ {"@id" => "http://example.com/c"}
311
330
  ]
312
331
  },
313
332
  {
@@ -318,7 +337,8 @@ describe JSON::LD::API do
318
337
  "http://example.com/b" => [{
319
338
  "@list" => [{"@id" => "http://example.com/e"}]
320
339
  }]
321
- }
340
+ },
341
+ {"@id" => "http://example.com/e"}
322
342
  ]
323
343
  }
324
344
  ]
@@ -337,15 +357,15 @@ describe JSON::LD::API do
337
357
  serialize(input, :useRdfType => false).should produce([{
338
358
  '@id' => "http://example.com/a",
339
359
  "@type" => ["http://example.com/b"]
340
- }], @debug)
360
+ }, {'@id' => "http://example.com/b"}], @debug)
341
361
  end
342
362
 
343
363
  it "does not use @type if set to true" do
344
364
  input = %(@prefix ex: <http://example.com/> . ex:a a ex:b .)
345
365
  serialize(input, :useRdfType => true).should produce([{
346
366
  '@id' => "http://example.com/a",
347
- RDF.type.to_s => [{"@id" => "http://example.com/b"}]
348
- }], @debug)
367
+ '@type' => ["http://example.com/b"]
368
+ }, {"@id" => "http://example.com/b"}], @debug)
349
369
  end
350
370
  end
351
371
 
@@ -363,7 +383,7 @@ describe JSON::LD::API do
363
383
  "http://www.w3.org/2000/01/rdf-schema#range" => [
364
384
  { "@id" => "http://www.w3.org/2001/XMLSchema#boolean" }
365
385
  ]
366
- }]
386
+ }, { "@id" => "http://www.w3.org/2001/XMLSchema#boolean" }]
367
387
  ],
368
388
  }.each do |t, (input, output)|
369
389
  it "#{t}" do
@@ -385,6 +405,6 @@ describe JSON::LD::API do
385
405
  g = ntstr.is_a?(String) ? parse(ntstr, options) : ntstr
386
406
  @debug << g.dump(:trig)
387
407
  statements = g.each_statement.to_a
388
- JSON::LD::API.fromRDF(statements, nil, options.merge(:debug => @debug))
408
+ JSON::LD::API.fromRDF(statements, options.merge(:debug => @debug))
389
409
  end
390
410
  end