json-ld 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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