json-ld 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/History.markdown +3 -0
  2. data/VERSION +1 -1
  3. data/bin/jsonld +134 -0
  4. data/lib/json/ld/api.rb +4 -4
  5. data/lib/json/ld/frame.rb +2 -1
  6. data/lib/json/ld/from_rdf.rb +1 -1
  7. data/spec/api_spec.rb +66 -0
  8. data/spec/compact_spec.rb +420 -0
  9. data/spec/evaluation_context_spec.rb +1039 -0
  10. data/spec/expand_spec.rb +625 -0
  11. data/spec/format_spec.rb +71 -0
  12. data/spec/frame_spec.rb +542 -0
  13. data/spec/from_rdf_spec.rb +316 -0
  14. data/spec/matchers.rb +67 -0
  15. data/spec/reader_spec.rb +79 -0
  16. data/spec/spec_helper.rb +56 -0
  17. data/spec/suite_helper.rb +184 -0
  18. data/spec/suite_spec.rb +104 -0
  19. data/spec/support/extensions.rb +10 -0
  20. data/spec/test-files/test-1-automatic.json +10 -0
  21. data/spec/test-files/test-1-compacted.json +10 -0
  22. data/spec/test-files/test-1-context.json +7 -0
  23. data/spec/test-files/test-1-expanded.json +5 -0
  24. data/spec/test-files/test-1-input.json +10 -0
  25. data/spec/test-files/test-1-normalized.json +8 -0
  26. data/spec/test-files/test-1-rdf.ttl +7 -0
  27. data/spec/test-files/test-2-automatic.json +27 -0
  28. data/spec/test-files/test-2-compacted.json +20 -0
  29. data/spec/test-files/test-2-context.json +7 -0
  30. data/spec/test-files/test-2-expanded.json +16 -0
  31. data/spec/test-files/test-2-input.json +20 -0
  32. data/spec/test-files/test-2-normalized.json +32 -0
  33. data/spec/test-files/test-2-rdf.ttl +14 -0
  34. data/spec/test-files/test-3-compacted.json +11 -0
  35. data/spec/test-files/test-3-context.json +8 -0
  36. data/spec/test-files/test-3-expanded.json +10 -0
  37. data/spec/test-files/test-3-input.json +11 -0
  38. data/spec/test-files/test-3-normalized.json +13 -0
  39. data/spec/test-files/test-3-rdf.ttl +7 -0
  40. data/spec/test-files/test-4-automatic.json +10 -0
  41. data/spec/test-files/test-4-compacted.json +10 -0
  42. data/spec/test-files/test-4-context.json +7 -0
  43. data/spec/test-files/test-4-expanded.json +6 -0
  44. data/spec/test-files/test-4-input.json +10 -0
  45. data/spec/test-files/test-4-rdf.ttl +5 -0
  46. data/spec/test-files/test-5-automatic.json +13 -0
  47. data/spec/test-files/test-5-compacted.json +13 -0
  48. data/spec/test-files/test-5-context.json +7 -0
  49. data/spec/test-files/test-5-expanded.json +9 -0
  50. data/spec/test-files/test-5-input.json +13 -0
  51. data/spec/test-files/test-5-rdf.ttl +6 -0
  52. data/spec/test-files/test-6-automatic.json +10 -0
  53. data/spec/test-files/test-6-compacted.json +10 -0
  54. data/spec/test-files/test-6-context.json +7 -0
  55. data/spec/test-files/test-6-expanded.json +10 -0
  56. data/spec/test-files/test-6-input.json +10 -0
  57. data/spec/test-files/test-6-rdf.ttl +5 -0
  58. data/spec/test-files/test-7-automatic.json +20 -0
  59. data/spec/test-files/test-7-compacted.json +23 -0
  60. data/spec/test-files/test-7-context.json +4 -0
  61. data/spec/test-files/test-7-expanded.json +20 -0
  62. data/spec/test-files/test-7-input.json +23 -0
  63. data/spec/test-files/test-7-rdf.ttl +13 -0
  64. data/spec/test-files/test-8-automatic.json +1 -0
  65. data/spec/test-files/test-8-compacted.json +34 -0
  66. data/spec/test-files/test-8-context.json +11 -0
  67. data/spec/test-files/test-8-expanded.json +24 -0
  68. data/spec/test-files/test-8-frame.json +18 -0
  69. data/spec/test-files/test-8-framed.json +29 -0
  70. data/spec/test-files/test-8-input.json +30 -0
  71. data/spec/test-files/test-8-rdf.ttl +15 -0
  72. data/spec/test-files/test-9-compacted.json +20 -0
  73. data/spec/test-files/test-9-context.json +13 -0
  74. data/spec/test-files/test-9-expanded.json +14 -0
  75. data/spec/test-files/test-9-input.json +12 -0
  76. data/spec/to_rdf_spec.rb +640 -0
  77. data/spec/writer_spec.rb +161 -0
  78. metadata +150 -22
@@ -0,0 +1,1039 @@
1
+ # coding: utf-8
2
+ $:.unshift "."
3
+ require 'spec_helper'
4
+ require 'rdf/spec/reader'
5
+
6
+ describe JSON::LD::EvaluationContext do
7
+ before(:each) {
8
+ @debug = []
9
+ @ctx_json = %q({
10
+ "@context": {
11
+ "name": "http://xmlns.com/foaf/0.1/name",
12
+ "homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"},
13
+ "avatar": {"@id": "http://xmlns.com/foaf/0.1/avatar", "@type": "@id"}
14
+ }
15
+ })
16
+ }
17
+ subject { JSON::LD::EvaluationContext.new(:debug => @debug, :validate => true)}
18
+
19
+ describe "#parse" do
20
+ context "remote" do
21
+ before(:each) do
22
+ @ctx = StringIO.new(@ctx_json)
23
+ def @ctx.content_type; "application/ld+json"; end
24
+ end
25
+
26
+ it "retrieves and parses a remote context document" do
27
+ RDF::Util::File.stub(:open_file).with("http://example.com/context").and_yield(@ctx)
28
+ ec = subject.parse("http://example.com/context")
29
+ ec.provided_context.should produce("http://example.com/context", @debug)
30
+ end
31
+
32
+ it "fails given a missing remote @context" do
33
+ RDF::Util::File.stub(:open_file).with("http://example.com/context").and_raise(IOError)
34
+ lambda {subject.parse("http://example.com/context")}.should raise_error(JSON::LD::InvalidContext, /Failed to parse remote context/)
35
+ end
36
+
37
+ it "creates mappings" do
38
+ RDF::Util::File.stub(:open_file).with("http://example.com/context").and_yield(@ctx)
39
+ ec = subject.parse("http://example.com/context")
40
+ ec.mappings.should produce({
41
+ "name" => "http://xmlns.com/foaf/0.1/name",
42
+ "homepage" => "http://xmlns.com/foaf/0.1/homepage",
43
+ "avatar" => "http://xmlns.com/foaf/0.1/avatar"
44
+ }, @debug)
45
+ end
46
+
47
+ it "allows a non-existing @context" do
48
+ ec = subject.parse(StringIO.new("{}"))
49
+ ec.mappings.should produce({}, @debug)
50
+ end
51
+ end
52
+
53
+ context "EvaluationContext" do
54
+ it "uses a duplicate of that provided" do
55
+ ec = subject.parse(StringIO.new(@ctx_json))
56
+ ec.mappings.should produce({
57
+ "name" => "http://xmlns.com/foaf/0.1/name",
58
+ "homepage" => "http://xmlns.com/foaf/0.1/homepage",
59
+ "avatar" => "http://xmlns.com/foaf/0.1/avatar"
60
+ }, @debug)
61
+ end
62
+ end
63
+
64
+ context "Array" do
65
+ before(:all) do
66
+ @ctx = [
67
+ {"foo" => "http://example.com/foo"},
68
+ {"bar" => "foo"}
69
+ ]
70
+ end
71
+
72
+ it "merges definitions from each context" do
73
+ ec = subject.parse(@ctx)
74
+ ec.mappings.should produce({
75
+ "foo" => "http://example.com/foo",
76
+ "bar" => "http://example.com/foo"
77
+ }, @debug)
78
+ end
79
+ end
80
+
81
+ context "Hash" do
82
+ it "extracts @language" do
83
+ subject.parse({
84
+ "@language" => "en"
85
+ }).default_language.should produce("en", @debug)
86
+ end
87
+
88
+ it "maps term with IRI value" do
89
+ subject.parse({
90
+ "foo" => "http://example.com/"
91
+ }).mappings.should produce({
92
+ "foo" => "http://example.com/"
93
+ }, @debug)
94
+ end
95
+
96
+ it "maps term with @id" do
97
+ subject.parse({
98
+ "foo" => {"@id" => "http://example.com/"}
99
+ }).mappings.should produce({
100
+ "foo" => "http://example.com/"
101
+ }, @debug)
102
+ end
103
+
104
+ it "associates @list coercion with predicate" do
105
+ subject.parse({
106
+ "foo" => {"@id" => "http://example.com/", "@container" => "@list"}
107
+ }).containers.should produce({
108
+ "foo" => '@list'
109
+ }, @debug)
110
+ end
111
+
112
+ it "associates @set coercion with predicate" do
113
+ subject.parse({
114
+ "foo" => {"@id" => "http://example.com/", "@container" => "@set"}
115
+ }).containers.should produce({
116
+ "foo" => '@set'
117
+ }, @debug)
118
+ end
119
+
120
+ it "associates @id coercion with predicate" do
121
+ subject.parse({
122
+ "foo" => {"@id" => "http://example.com/", "@type" => "@id"}
123
+ }).coercions.should produce({
124
+ "foo" => "@id"
125
+ }, @debug)
126
+ end
127
+
128
+ it "associates datatype coercion with predicate" do
129
+ subject.parse({
130
+ "foo" => {"@id" => "http://example.com/", "@type" => RDF::XSD.string.to_s}
131
+ }).coercions.should produce({
132
+ "foo" => RDF::XSD.string.to_s
133
+ }, @debug)
134
+ end
135
+
136
+ it "associates language coercion with predicate" do
137
+ subject.parse({
138
+ "foo" => {"@id" => "http://example.com/", "@language" => "en"}
139
+ }).languages.should produce({
140
+ "foo" => "en"
141
+ }, @debug)
142
+ end
143
+
144
+ it "expands chains of term definition/use with string values" do
145
+ subject.parse({
146
+ "foo" => "bar",
147
+ "bar" => "baz",
148
+ "baz" => "http://example.com/"
149
+ }).mappings.should produce({
150
+ "foo" => "http://example.com/",
151
+ "bar" => "http://example.com/",
152
+ "baz" => "http://example.com/"
153
+ }, @debug)
154
+ end
155
+
156
+ context "with null" do
157
+ it "removes @language if set to null" do
158
+ subject.parse([
159
+ {
160
+ "@language" => "en"
161
+ },
162
+ {
163
+ "@language" => nil
164
+ }
165
+ ]).default_language.should produce(nil, @debug)
166
+ end
167
+
168
+ it "loads initial context" do
169
+ init_ec = JSON::LD::EvaluationContext.new
170
+ nil_ec = subject.parse(nil)
171
+ nil_ec.default_language.should == init_ec.default_language
172
+ nil_ec.languages.should == init_ec.languages
173
+ nil_ec.mappings.should == init_ec.mappings
174
+ nil_ec.coercions.should == init_ec.coercions
175
+ nil_ec.containers.should == init_ec.containers
176
+ end
177
+
178
+ it "removes a term definition" do
179
+ subject.parse({"name" => nil}).mapping("name").should be_nil
180
+ end
181
+ end
182
+ end
183
+
184
+ describe "Syntax Errors" do
185
+ {
186
+ "malformed JSON" => StringIO.new(%q({"@context": {"foo" "http://malformed/"})),
187
+ "no @id, @type, or @container" => {"foo" => {}},
188
+ "value as array" => {"foo" => []},
189
+ "@id as object" => {"foo" => {"@id" => {}}},
190
+ "@id as array" => {"foo" => {"@id" => []}},
191
+ "@type as object" => {"foo" => {"@type" => {}}},
192
+ "@type as array" => {"foo" => {"@type" => []}},
193
+ "@type as @list" => {"foo" => {"@type" => "@list"}},
194
+ "@type as @list" => {"foo" => {"@type" => "@set"}},
195
+ "@container as object" => {"foo" => {"@container" => {}}},
196
+ "@container as array" => {"foo" => {"@container" => []}},
197
+ "@container as string" => {"foo" => {"@container" => "true"}},
198
+ "@language as @id" => {"@language" => {"@id" => "http://example.com/"}},
199
+ }.each do |title, context|
200
+ it title do
201
+ lambda {
202
+ ec = subject.parse(context)
203
+ ec.serialize.should produce({}, @debug)
204
+ }.should raise_error(JSON::LD::InvalidContext::Syntax)
205
+ end
206
+ end
207
+
208
+ (JSON::LD::KEYWORDS - %w(@language)).each do |kw|
209
+ it "does not redefined #{kw} as a string" do
210
+ lambda {
211
+ ec = subject.parse({kw => "http://example.com/"})
212
+ ec.serialize.should produce({}, @debug)
213
+ }.should raise_error(JSON::LD::InvalidContext::Syntax)
214
+ end
215
+
216
+ it "does not redefined #{kw} with an @id" do
217
+ lambda {
218
+ ec = subject.parse({kw => {"@id" => "http://example.com/"}})
219
+ ec.serialize.should produce({}, @debug)
220
+ }.should raise_error(JSON::LD::InvalidContext::Syntax)
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "Load Errors" do
226
+ {
227
+ "fixme" => "FIXME",
228
+ }.each do |title, context|
229
+ it title do
230
+ lambda { subject.parse(context) }.should raise_error(JSON::LD::InvalidContext::LoadError)
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "#serialize" do
237
+ it "uses provided context document" do
238
+ ctx = StringIO.new(@ctx_json)
239
+ def ctx.content_type; "application/ld+json"; end
240
+
241
+ RDF::Util::File.stub(:open_file).with("http://example.com/context").and_yield(ctx)
242
+ ec = subject.parse("http://example.com/context")
243
+ ec.serialize.should produce({
244
+ "@context" => "http://example.com/context"
245
+ }, @debug)
246
+ end
247
+
248
+ it "uses provided context array" do
249
+ ctx = [
250
+ {"foo" => "http://example.com/"},
251
+ {"baz" => "bob"}
252
+ ]
253
+
254
+ ec = subject.parse(ctx)
255
+ ec.serialize.should produce({
256
+ "@context" => ctx
257
+ }, @debug)
258
+ end
259
+
260
+ it "uses provided context hash" do
261
+ ctx = {"foo" => "http://example.com/"}
262
+
263
+ ec = subject.parse(ctx)
264
+ ec.serialize.should produce({
265
+ "@context" => ctx
266
+ }, @debug)
267
+ end
268
+
269
+ it "@language" do
270
+ subject.default_language = "en"
271
+ subject.serialize.should produce({
272
+ "@context" => {
273
+ "@language" => "en"
274
+ }
275
+ }, @debug)
276
+ end
277
+
278
+ it "term mappings" do
279
+ subject.set_mapping("foo", "http://example.com/")
280
+ subject.serialize.should produce({
281
+ "@context" => {
282
+ "foo" => "http://example.com/"
283
+ }
284
+ }, @debug)
285
+ end
286
+
287
+ it "@type with dependent prefixes in a single context" do
288
+ subject.set_mapping("xsd", RDF::XSD.to_uri.to_s)
289
+ subject.set_mapping("homepage", RDF::FOAF.homepage.to_s)
290
+ subject.set_coerce("homepage", "@id")
291
+ subject.serialize.should produce({
292
+ "@context" => {
293
+ "xsd" => RDF::XSD.to_uri,
294
+ "homepage" => {"@id" => RDF::FOAF.homepage.to_s, "@type" => "@id"}
295
+ }
296
+ }, @debug)
297
+ end
298
+
299
+ it "@list with @id definition in a single context" do
300
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
301
+ subject.set_container("knows", '@list')
302
+ subject.serialize.should produce({
303
+ "@context" => {
304
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@container" => "@list"}
305
+ }
306
+ }, @debug)
307
+ end
308
+
309
+ it "@set with @id definition in a single context" do
310
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
311
+ subject.set_container("knows", '@set')
312
+ subject.serialize.should produce({
313
+ "@context" => {
314
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@container" => "@set"}
315
+ }
316
+ }, @debug)
317
+ end
318
+
319
+ it "@language with @id definition in a single context" do
320
+ subject.set_mapping("name", RDF::FOAF.name.to_s)
321
+ subject.set_language("name", 'en')
322
+ subject.serialize.should produce({
323
+ "@context" => {
324
+ "name" => {"@id" => RDF::FOAF.name.to_s, "@language" => "en"}
325
+ }
326
+ }, @debug)
327
+ end
328
+
329
+ it "@language with @id definition in a single context and equivalent default" do
330
+ subject.set_mapping("name", RDF::FOAF.name.to_s)
331
+ subject.default_language = 'en'
332
+ subject.set_language("name", 'en')
333
+ subject.serialize.should produce({
334
+ "@context" => {
335
+ "@language" => 'en',
336
+ "name" => {"@id" => RDF::FOAF.name.to_s}
337
+ }
338
+ }, @debug)
339
+ end
340
+
341
+ it "@language with @id definition in a single context and different default" do
342
+ subject.set_mapping("name", RDF::FOAF.name.to_s)
343
+ subject.default_language = 'en'
344
+ subject.set_language("name", 'de')
345
+ subject.serialize.should produce({
346
+ "@context" => {
347
+ "@language" => 'en',
348
+ "name" => {"@id" => RDF::FOAF.name.to_s, "@language" => "de"}
349
+ }
350
+ }, @debug)
351
+ end
352
+
353
+ it "null @language with @id definition in a single context and default" do
354
+ subject.set_mapping("name", RDF::FOAF.name.to_s)
355
+ subject.default_language = 'en'
356
+ subject.set_language("name", nil)
357
+ subject.serialize.should produce({
358
+ "@context" => {
359
+ "@language" => 'en',
360
+ "name" => {"@id" => RDF::FOAF.name.to_s, "@language" => nil}
361
+ }
362
+ }, @debug)
363
+ end
364
+
365
+ it "prefix with @type and @list" do
366
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
367
+ subject.set_coerce("knows", "@id")
368
+ subject.set_container("knows", '@list')
369
+ subject.serialize.should produce({
370
+ "@context" => {
371
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@type" => "@id", "@container" => "@list"}
372
+ }
373
+ }, @debug)
374
+ end
375
+
376
+ it "prefix with @type and @set" do
377
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
378
+ subject.set_coerce("knows", "@id")
379
+ subject.set_container("knows", '@set')
380
+ subject.serialize.should produce({
381
+ "@context" => {
382
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@type" => "@id", "@container" => "@set"}
383
+ }
384
+ }, @debug)
385
+ end
386
+
387
+ it "CURIE with @type" do
388
+ subject.set_mapping("foaf", RDF::FOAF.to_uri.to_s)
389
+ subject.set_container("foaf:knows", '@list')
390
+ subject.serialize.should produce({
391
+ "@context" => {
392
+ "foaf" => RDF::FOAF.to_uri,
393
+ "foaf:knows" => {"@container" => "@list"}
394
+ }
395
+ }, @debug)
396
+ end
397
+
398
+ it "does not use aliased @id in key position" do
399
+ subject.set_mapping("id", '@id')
400
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
401
+ subject.set_container("knows", '@list')
402
+ subject.serialize.should produce({
403
+ "@context" => {
404
+ "id" => "@id",
405
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@container" => "@list"}
406
+ }
407
+ }, @debug)
408
+ end
409
+
410
+ it "does not use aliased @id in value position" do
411
+ subject.set_mapping("id", "@id")
412
+ subject.set_mapping("foaf", RDF::FOAF.to_uri.to_s)
413
+ subject.set_coerce("foaf:homepage", "@id")
414
+ subject.serialize.should produce({
415
+ "@context" => {
416
+ "foaf" => RDF::FOAF.to_uri.to_s,
417
+ "id" => "@id",
418
+ "foaf:homepage" => {"@type" => "@id"}
419
+ }
420
+ }, @debug)
421
+ end
422
+
423
+ it "does not use aliased @type" do
424
+ subject.set_mapping("type", "@type")
425
+ subject.set_mapping("foaf", RDF::FOAF.to_uri.to_s)
426
+ subject.set_coerce("foaf:homepage", "@id")
427
+ subject.serialize.should produce({
428
+ "@context" => {
429
+ "foaf" => RDF::FOAF.to_uri.to_s,
430
+ "type" => "@type",
431
+ "foaf:homepage" => {"@type" => "@id"}
432
+ }
433
+ }, @debug)
434
+ end
435
+
436
+ it "does not use aliased @container" do
437
+ subject.set_mapping("container", '@container')
438
+ subject.set_mapping("knows", RDF::FOAF.knows.to_s)
439
+ subject.set_container("knows", '@list')
440
+ subject.serialize.should produce({
441
+ "@context" => {
442
+ "container" => "@container",
443
+ "knows" => {"@id" => RDF::FOAF.knows.to_s, "@container" => "@list"}
444
+ }
445
+ }, @debug)
446
+ end
447
+
448
+ it "compacts IRIs to CURIEs" do
449
+ subject.set_mapping("ex", 'http://example.org/')
450
+ subject.set_mapping("term", 'http://example.org/term')
451
+ subject.set_coerce("term", "http://example.org/datatype")
452
+ subject.serialize.should produce({
453
+ "@context" => {
454
+ "ex" => 'http://example.org/',
455
+ "term" => {"@id" => "ex:term", "@type" => "ex:datatype"}
456
+ }
457
+ }, @debug)
458
+ end
459
+
460
+ context "extra keys or values" do
461
+ {
462
+ "extra key" => {
463
+ :input => {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}},
464
+ :result => {"@context" => {"foo" => {"@id" => "http://example.com/foo", "@baz" => "foobar"}}}
465
+ }
466
+ }.each do |title, params|
467
+ it title do
468
+ ec = subject.parse(params[:input])
469
+ ec.serialize.should produce(params[:result], @debug)
470
+ end
471
+ end
472
+ end
473
+
474
+ end
475
+
476
+ describe "#expand_iri" do
477
+ before(:each) do
478
+ subject.set_mapping("ex", "http://example.org/")
479
+ subject.set_mapping("", "http://empty/")
480
+ subject.set_mapping("_", "http://underscore/")
481
+ end
482
+
483
+ it "bnode" do
484
+ subject.expand_iri("_:a").should be_a(RDF::Node)
485
+ end
486
+
487
+ context "relative IRI" do
488
+ {
489
+ :subject => true,
490
+ :predicate => false,
491
+ :object => true,
492
+ :datatype => false
493
+ }.each do |position, r|
494
+ context "as #{position}" do
495
+ {
496
+ "absolute IRI" => ["http://example.org/", "http://example.org/", true],
497
+ "term" => ["ex", "http://example.org/", true],
498
+ "prefix:suffix" => ["ex:suffix", "http://example.org/suffix", true],
499
+ "keyword" => ["@type", "@type", true],
500
+ "empty" => [":suffix", "http://empty/suffix", true],
501
+ "unmapped" => ["foo", "foo", false],
502
+ "empty term" => ["", "http://empty/", true],
503
+ "another abs IRI"=>["ex://foo", "ex://foo", true],
504
+ "absolute IRI looking like a curie" =>
505
+ ["foo:bar", "foo:bar", true],
506
+ "bnode" => ["_:foo", RDF::Node("foo"), true],
507
+ "_" => ["_", "http://underscore/", true],
508
+ }.each do |title, (input,result,abs)|
509
+ result = nil unless r || abs
510
+ result = nil if title == 'unmapped'
511
+ it title do
512
+ subject.expand_iri(input).should produce(result, @debug)
513
+ end
514
+ end
515
+ end
516
+ end
517
+
518
+ context "with base IRI" do
519
+ {
520
+ :subject => true,
521
+ :predicate => false,
522
+ :object => true,
523
+ :datatype => false
524
+ }.each do |position, r|
525
+ context "as #{position}" do
526
+ before(:each) do
527
+ subject.instance_variable_set(:@base, RDF::URI("http://example.org/"))
528
+ subject.mappings.delete("")
529
+ end
530
+
531
+ {
532
+ "base" => ["", RDF::URI("http://example.org/")],
533
+ "relative" => ["a/b", RDF::URI("http://example.org/a/b")],
534
+ "hash" => ["#a", RDF::URI("http://example.org/#a")],
535
+ "absolute" => ["http://foo/", RDF::URI("http://foo/")]
536
+ }.each do |title, (input,result)|
537
+ result = nil unless r || title == 'absolute'
538
+ it title do
539
+ subject.expand_iri(input, :position => position).should produce(result, @debug)
540
+ end
541
+ end
542
+ end
543
+ end
544
+ end
545
+ end
546
+ end
547
+
548
+ describe "#compact_iri" do
549
+ before(:each) do
550
+ subject.set_mapping("ex", "http://example.org/")
551
+ subject.set_mapping("", "http://empty/")
552
+ subject.set_mapping("http://example.com/null", nil)
553
+ end
554
+
555
+ {
556
+ "absolute IRI" => ["http://example.com/", "http://example.com/"],
557
+ "term" => ["ex", "http://example.org/"],
558
+ "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
559
+ "keyword" => ["@type", "@type"],
560
+ "empty" => [":suffix", "http://empty/suffix"],
561
+ "unmapped" => ["foo", "foo"],
562
+ "bnode" => ["_:a", RDF::Node("a")],
563
+ "null IRI" => [nil, "http://example.com/null"],
564
+ }.each do |title, (result, input)|
565
+ it title do
566
+ subject.compact_iri(input).should produce(result, @debug)
567
+ end
568
+ end
569
+
570
+ context "with value" do
571
+ let(:ctx) do
572
+ c = subject.parse({
573
+ "xsd" => RDF::XSD.to_s,
574
+ "plain" => "http://example.com/plain",
575
+ "lang" => {"@id" => "http://example.com/lang", "@language" => "en"},
576
+ "bool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean"},
577
+ "integer" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer"},
578
+ "double" => {"@id" => "http://example.com/double", "@type" => "xsd:double"},
579
+ "date" => {"@id" => "http://example.com/date", "@type" => "xsd:date"},
580
+ "id" => {"@id" => "http://example.com/id", "@type" => "@id"},
581
+ "listplain" => {"@id" => "http://example.com/plain", "@container" => "@list"},
582
+ "listlang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@list"},
583
+ "listbool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@list"},
584
+ "listinteger" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@list"},
585
+ "listdouble" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@list"},
586
+ "listdate" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@list"},
587
+ "listid" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@list"},
588
+ "setplain" => {"@id" => "http://example.com/plain", "@container" => "@set"},
589
+ "setlang" => {"@id" => "http://example.com/lang", "@language" => "en", "@container" => "@set"},
590
+ "setbool" => {"@id" => "http://example.com/bool", "@type" => "xsd:boolean", "@container" => "@set"},
591
+ "setinteger" => {"@id" => "http://example.com/integer", "@type" => "xsd:integer", "@container" => "@set"},
592
+ "setdouble" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@set"},
593
+ "setdate" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@set"},
594
+ "setid" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@set"},
595
+ })
596
+ @debug.clear
597
+ c
598
+ end
599
+
600
+ {
601
+ "setplain" => [
602
+ {"@value" => "foo"},
603
+ {"@value" => "de", "@language" => "de"},
604
+ {"@value" => "other dt", "@language" => "http://example.com/other-datatype"}
605
+ ],
606
+ "setlang" => [{"@value" => "en", "@language" => "en"}],
607
+ "setbool" => [{"@value" => true}, {"@value" => false}, {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
608
+ "setinteger" => [{"@value" => 1}, {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
609
+ "setdouble" => [{"@value" => 1.1}, {"@value" => "1", "@type" => RDF::XSD.double.to_s}],
610
+ "setdate" => [{"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}],
611
+ }.each do |prop, values|
612
+ context "uses #{prop}", :pending => "does algorithm favor @set?" do
613
+ values.each do |value|
614
+ it "for #{value.inspect}" do
615
+ ctx.compact_iri("http://example.com/#{prop.sub('set', '')}", :value => value).should produce(prop, @debug)
616
+ end
617
+ end
618
+ end
619
+ end
620
+
621
+ context "for @list" do
622
+ {
623
+ "listplain" => [
624
+ [{"@value" => "foo"}],
625
+ [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}],
626
+ [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1.1}],
627
+ [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => true}],
628
+ [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}],
629
+ [{"@value" => "de", "@language" => "de"}, {"@value" => "jp", "@language" => "jp"}],
630
+ ],
631
+ "listlang" => [[{"@value" => "en", "@language" => "en"}]],
632
+ "listbool" => [[{"@value" => true}], [{"@value" => false}], [{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}]],
633
+ "listinteger" => [[{"@value" => 1}], [{"@value" => "1", "@type" => RDF::XSD.integer.to_s}]],
634
+ "listdouble" => [[{"@value" => 1.1}], [{"@value" => "1", "@type" => RDF::XSD.double.to_s}]],
635
+ "listdate" => [[{"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}]],
636
+ }.each do |prop, values|
637
+ context "uses #{prop}" do
638
+ values.each do |value|
639
+ it "for #{{"@list" => value}.inspect}" do
640
+ ctx.compact_iri("http://example.com/#{prop.sub('list', '')}", :value => {"@list" => value}).should produce(prop, @debug)
641
+ end
642
+ end
643
+ end
644
+ end
645
+ end
646
+ end
647
+ end
648
+
649
+ describe "#term_rank" do
650
+ {
651
+ "no coercions" => {
652
+ :defn => {},
653
+ "boolean value" => {:value => {"@value" => true}, :rank => 2},
654
+ "integer value" => {:value => {"@value" => 1}, :rank => 2},
655
+ "double value" => {:value => {"@value" => 1.1}, :rank => 2},
656
+ "string value" => {:value => {"@value" => "foo"}, :rank => 3},
657
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 1},
658
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 1},
659
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 1},
660
+ "null" => {:value => nil, :rank => 3},
661
+ },
662
+ "boolean" => {
663
+ :defn => {"@type" => RDF::XSD.boolean.to_s},
664
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
665
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
666
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
667
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
668
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
669
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
670
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
671
+ "value boolean" => {:value => {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}, :rank => 3},
672
+ "null" => {:value => nil, :rank => 3},
673
+ },
674
+ "integer" => {
675
+ :defn => {"@type" => RDF::XSD.integer.to_s},
676
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
677
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
678
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
679
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
680
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
681
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
682
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
683
+ "value integer" => {:value => {"@value" => "1", "@type" => RDF::XSD.integer.to_s}, :rank => 3},
684
+ "null" => {:value => nil, :rank => 3},
685
+ },
686
+ "double" => {
687
+ :defn => {"@type" => RDF::XSD.double.to_s},
688
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
689
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
690
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
691
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
692
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
693
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
694
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
695
+ "value double" => {:value => {"@value" => "1.1", "@type" => RDF::XSD.double.to_s}, :rank => 3},
696
+ "null" => {:value => nil, :rank => 3},
697
+ },
698
+ "date" => {
699
+ :defn => {"@type" => RDF::XSD.date.to_s},
700
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
701
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
702
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
703
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
704
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 3},
705
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
706
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
707
+ "null" => {:value => nil, :rank => 3},
708
+ },
709
+ "lang" => {
710
+ :defn => {"@language" => "en"},
711
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
712
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
713
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
714
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
715
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
716
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
717
+ "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
718
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
719
+ "null" => {:value => nil, :rank => 3},
720
+ },
721
+ "id" => {
722
+ :defn => {"@type" => "@id"},
723
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
724
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
725
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
726
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
727
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
728
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
729
+ "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
730
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 3},
731
+ "null" => {:value => nil, :rank => 3},
732
+ },
733
+ }.each do |title, properties|
734
+ context title do
735
+ let(:ctx) do
736
+ subject.parse({
737
+ "term" => properties[:defn].merge("@id" => "http://example.org/term")
738
+ })
739
+ end
740
+ properties.each do |type, defn|
741
+ next unless type.is_a?(String)
742
+ it "returns #{defn[:rank]} for #{type}" do
743
+ ctx.send(:term_rank, "term", defn[:value]).should produce(defn[:rank], @debug)
744
+ end
745
+ end
746
+ end
747
+ end
748
+
749
+ context "with default language" do
750
+ before(:each) {subject.default_language = "en"}
751
+ {
752
+ "no coercions" => {
753
+ :defn => {},
754
+ "boolean value" => {:value => {"@value" => true}, :rank => 2},
755
+ "integer value" => {:value => {"@value" => 1}, :rank => 2},
756
+ "double value" => {:value => {"@value" => 1.1}, :rank => 2},
757
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
758
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 1},
759
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
760
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 1},
761
+ "value string" => {:value => {"@value" => "foo"}, :rank => 0},
762
+ "null" => {:value => nil, :rank => 3},
763
+ },
764
+ "boolean" => {
765
+ :defn => {"@type" => RDF::XSD.boolean.to_s},
766
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
767
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
768
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
769
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
770
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
771
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
772
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
773
+ "value boolean" => {:value => {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}, :rank => 3},
774
+ "null" => {:value => nil, :rank => 3},
775
+ },
776
+ "integer" => {
777
+ :defn => {"@type" => RDF::XSD.integer.to_s},
778
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
779
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
780
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
781
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
782
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
783
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
784
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
785
+ "value integer" => {:value => {"@value" => "1", "@type" => RDF::XSD.integer.to_s}, :rank => 3},
786
+ "null" => {:value => nil, :rank => 3},
787
+ },
788
+ "double" => {
789
+ :defn => {"@type" => RDF::XSD.double.to_s},
790
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
791
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
792
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
793
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
794
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
795
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
796
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
797
+ "value double" => {:value => {"@value" => "1.1", "@type" => RDF::XSD.double.to_s}, :rank => 3},
798
+ "null" => {:value => nil, :rank => 3},
799
+ },
800
+ "date" => {
801
+ :defn => {"@type" => RDF::XSD.date.to_s},
802
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
803
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
804
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
805
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
806
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 3},
807
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
808
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
809
+ "null" => {:value => nil, :rank => 3},
810
+ },
811
+ "lang" => {
812
+ :defn => {"@language" => "en"},
813
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
814
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
815
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
816
+ "string value" => {:value => {"@value" => "foo"}, :rank => 0},
817
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
818
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
819
+ "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
820
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
821
+ "null" => {:value => nil, :rank => 3},
822
+ },
823
+ "null lang" => {
824
+ :defn => {"@language" => nil},
825
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
826
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
827
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
828
+ "string value" => {:value => {"@value" => "foo"}, :rank => 3},
829
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
830
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
831
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
832
+ "null" => {:value => nil, :rank => 3},
833
+ },
834
+ "id" => {
835
+ :defn => {"@type" => "@id"},
836
+ "boolean value" => {:value => {"@value" => true}, :rank => 1},
837
+ "integer value" => {:value => {"@value" => 1}, :rank => 1},
838
+ "double value" => {:value => {"@value" => 1.1}, :rank => 1},
839
+ "string" => {:value => {"@value" => "foo"}, :rank => 0},
840
+ "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
841
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 0},
842
+ "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
843
+ "id" => {:value => {"@id" => "http://example/id"}, :rank => 3},
844
+ "null" => {:value => nil, :rank => 3},
845
+ },
846
+ }.each do |title, properties|
847
+ context title do
848
+ let(:ctx) do
849
+ subject.parse({
850
+ "term" => properties[:defn].merge("@id" => "http://example.org/term")
851
+ })
852
+ end
853
+ properties.each do |type, defn|
854
+ next unless type.is_a?(String)
855
+ it "returns #{defn[:rank]} for #{type}" do
856
+ ctx.send(:term_rank, "term", defn[:value]).should produce(defn[:rank], @debug)
857
+ end
858
+ end
859
+ end
860
+ end
861
+ end
862
+ end
863
+
864
+ describe "#expand_value" do
865
+ before(:each) do
866
+ subject.set_mapping("dc", RDF::DC.to_uri.to_s)
867
+ subject.set_mapping("ex", "http://example.org/")
868
+ subject.set_mapping("foaf", RDF::FOAF.to_uri.to_s)
869
+ subject.set_mapping("xsd", RDF::XSD.to_uri.to_s)
870
+ subject.set_coerce("foaf:age", RDF::XSD.integer.to_s)
871
+ subject.set_coerce("foaf:knows", "@id")
872
+ subject.set_coerce("dc:created", RDF::XSD.date.to_s)
873
+ subject.set_coerce("ex:double", RDF::XSD.double.to_s)
874
+ subject.set_coerce("ex:boolean", RDF::XSD.boolean.to_s)
875
+ end
876
+
877
+ {
878
+ "absolute IRI" => ["foaf:knows", "http://example.com/", {"@id" => "http://example.com/"}],
879
+ "term" => ["foaf:knows", "ex", {"@id" => "http://example.org/"}],
880
+ "prefix:suffix" => ["foaf:knows", "ex:suffix", {"@id" => "http://example.org/suffix"}],
881
+ "no IRI" => ["foo", "http://example.com/", {"@value" => "http://example.com/"}],
882
+ "no term" => ["foo", "ex", {"@value" => "ex"}],
883
+ "no prefix" => ["foo", "ex:suffix", {"@value" => "ex:suffix"}],
884
+ "integer" => ["foaf:age", "54", {"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
885
+ "date " => ["dc:created", "2011-12-27Z", {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
886
+ "native boolean" => ["foo", true, {"@value" => true}],
887
+ "native integer" => ["foo", 1, {"@value" => 1}],
888
+ "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
889
+ "native date" => ["foo", Date.parse("2011-12-27Z"), {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
890
+ "native time" => ["foo", Time.parse("10:11:12Z"), {"@value" => "10:11:12Z", "@type" => RDF::XSD.time.to_s}],
891
+ "native dateTime" =>["foo", DateTime.parse("2011-12-27T10:11:12Z"), {"@value" => "2011-12-27T10:11:12Z", "@type" => RDF::XSD.dateTime.to_s}],
892
+ "rdf boolean" => ["foo", RDF::Literal(true), {"@value" => true}],
893
+ "rdf integer" => ["foo", RDF::Literal(1), {"@value" => 1}],
894
+ "rdf decimal" => ["foo", RDF::Literal::Decimal.new(1.1), {"@value" => "1.1", "@type" => RDF::XSD.decimal.to_s}],
895
+ "rdf double" => ["foo", RDF::Literal::Double.new(1.1), {"@value" => 1.1}],
896
+ "rdf URI" => ["foo", RDF::URI("foo"), {"@id" => "foo"}],
897
+ "rdf date " => ["foo", RDF::Literal(Date.parse("2011-12-27Z")), {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
898
+ }.each do |title, (key, compacted, expanded)|
899
+ it title do
900
+ subject.expand_value(key, compacted).should produce(expanded, @debug)
901
+ end
902
+ end
903
+
904
+ context "@language" do
905
+ before(:each) {subject.default_language = "en"}
906
+ {
907
+ "no IRI" => ["foo", "http://example.com/", {"@value" => "http://example.com/", "@language" => "en"}],
908
+ "no term" => ["foo", "ex", {"@value" => "ex", "@language" => "en"}],
909
+ "no prefix" => ["foo", "ex:suffix", {"@value" => "ex:suffix", "@language" => "en"}],
910
+ "native boolean" => ["foo", true, {"@value" => true}],
911
+ "native integer" => ["foo", 1, {"@value" => 1}],
912
+ "native double" => ["foo", 1.1, {"@value" => 1.1}],
913
+ }.each do |title, (key, compacted, expanded)|
914
+ it title do
915
+ subject.expand_value(key, compacted).should produce(expanded, @debug)
916
+ end
917
+ end
918
+ end
919
+
920
+ context "coercion" do
921
+ before(:each) {subject.default_language = "en"}
922
+ {
923
+ "boolean-boolean" => ["ex:boolean", true, {"@value" => true}],
924
+ "boolean-double" => ["ex:double", true, {"@value" => "true", "@type" => RDF::XSD.double.to_s}],
925
+ "boolean-int" => ["foaf:age", true, {"@value" => true}],
926
+ "double-boolean" => ["ex:boolean", 1.1, {"@value" => "1.1", "@type" => RDF::XSD.boolean.to_s}],
927
+ "double-double" => ["ex:double", 1.1, {"@value" => "1.1E0", "@type" => RDF::XSD.double.to_s}],
928
+ "double-int" => ["foaf:age", 1.1, {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
929
+ "int-boolean" => ["ex:boolean", 1, {"@value" => "1", "@type" => RDF::XSD.boolean.to_s}],
930
+ "int-double" => ["ex:double", 1, {"@value" => "1.0E0", "@type" => RDF::XSD.double.to_s}],
931
+ "int-int" => ["foaf:age", 1, {"@value" => 1}],
932
+ "string-boolean" => ["ex:boolean", "foo", {"@value" => "foo", "@type" => RDF::XSD.boolean.to_s}],
933
+ "string-double" => ["ex:double", "foo", {"@value" => "foo", "@type" => RDF::XSD.double.to_s}],
934
+ "string-int" => ["foaf:age", "foo", {"@value" => "foo", "@type" => RDF::XSD.integer.to_s}],
935
+ }.each do |title, (key, compacted, expanded)|
936
+ it title do
937
+ subject.expand_value(key, compacted).should produce(expanded, @debug)
938
+ end
939
+ end
940
+ end
941
+ end
942
+
943
+ describe "compact_value" do
944
+ before(:each) do
945
+ subject.set_mapping("dc", RDF::DC.to_uri.to_s)
946
+ subject.set_mapping("ex", "http://example.org/")
947
+ subject.set_mapping("foaf", RDF::FOAF.to_uri.to_s)
948
+ subject.set_mapping("xsd", RDF::XSD.to_uri.to_s)
949
+ subject.set_mapping("list", "http://example.org/list")
950
+ subject.set_mapping("nolang", "http://example.org/nolang")
951
+ subject.set_coerce("foaf:age", RDF::XSD.integer.to_s)
952
+ subject.set_coerce("foaf:knows", "@id")
953
+ subject.set_coerce("dc:created", RDF::XSD.date.to_s)
954
+ subject.set_container("list", "@list")
955
+ subject.set_language("nolang", nil)
956
+ end
957
+
958
+ {
959
+ "absolute IRI" => ["foaf:knows", "http://example.com/", {"@id" => "http://example.com/"}],
960
+ "term" => ["foaf:knows", "ex", {"@id" => "http://example.org/"}],
961
+ "prefix:suffix" => ["foaf:knows", "ex:suffix", {"@id" => "http://example.org/suffix"}],
962
+ "integer" => ["foaf:age", "54", {"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
963
+ "date " => ["dc:created", "2011-12-27Z", {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
964
+ "no IRI" => ["foo", {"@id" =>"http://example.com/"},{"@id" => "http://example.com/"}],
965
+ "no IRI (term)" => ["foo", {"@id" => "ex"}, {"@id" => "http://example.org/"}],
966
+ "no IRI (CURIE)" => ["foo", {"@id" => "foaf:Person"}, {"@id" => RDF::FOAF.Person.to_s}],
967
+ "no boolean" => ["foo", {"@value" => "true", "@type" => "xsd:boolean"},{"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
968
+ "no integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"},{"@value" => "54", "@type" => RDF::XSD.integer.to_s}],
969
+ "no date " => ["foo", {"@value" => "2011-12-27Z", "@type" => "xsd:date"}, {"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
970
+ "no string " => ["foo", "string", {"@value" => "string"}],
971
+ "no lang " => ["nolang", "string", {"@value" => "string"}],
972
+ "native boolean" => ["foo", true, {"@value" => true}],
973
+ "native integer" => ["foo", 1, {"@value" => 1}],
974
+ "native integer(list)"=>["list", 1, {"@value" => 1}],
975
+ "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
976
+ }.each do |title, (key, compacted, expanded)|
977
+ it title do
978
+ subject.compact_value(key, expanded).should produce(compacted, @debug)
979
+ end
980
+ end
981
+
982
+ context "@language" do
983
+ {
984
+ "@id" => ["foo", {"@id" => "foo"}, {"@id" => "foo"}],
985
+ "integer" => ["foo", {"@value" => "54", "@type" => "xsd:integer"}, {"@value" => "54", "@type" => "xsd:integer"}],
986
+ "date" => ["foo", {"@value" => "2011-12-27Z","@type" => "xsd:date"},{"@value" => "2011-12-27Z", "@type" => RDF::XSD.date.to_s}],
987
+ "no lang" => ["foo", {"@value" => "foo" }, {"@value" => "foo"}],
988
+ "same lang" => ["foo", "foo", {"@value" => "foo", "@language" => "en"}],
989
+ "other lang" => ["foo", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
990
+ "no lang with @type coercion" => ["dc:created", {"@value" => "foo"}, {"@value" => "foo"}],
991
+ "no lang with @id coercion" => ["foaf:knows", {"@value" => "foo"}, {"@value" => "foo"}],
992
+ "no lang with @language=null" => ["nolang", "string", {"@value" => "string"}],
993
+ "same lang with @type coercion" => ["dc:created", {"@value" => "foo"}, {"@value" => "foo"}],
994
+ "same lang with @id coercion" => ["foaf:knows", {"@value" => "foo"}, {"@value" => "foo"}],
995
+ "other lang with @type coercion" => ["dc:created", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
996
+ "other lang with @id coercion" => ["foaf:knows", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
997
+ "native boolean" => ["foo", true, {"@value" => true}],
998
+ "native integer" => ["foo", 1, {"@value" => 1}],
999
+ "native integer(list)" => ["list", 1, {"@value" => 1}],
1000
+ "native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
1001
+ }.each do |title, (key, compacted, expanded)|
1002
+ it title do
1003
+ subject.default_language = "en"
1004
+ subject.compact_value(key, expanded).should produce(compacted, @debug)
1005
+ end
1006
+ end
1007
+ end
1008
+
1009
+ [[], true, false, 1, 1.1, "string"].each do |v|
1010
+ it "raises error given #{v.class}" do
1011
+ lambda {subject.compact_value("foo", v)}.should raise_error(JSON::LD::ProcessingError::Lossy)
1012
+ end
1013
+ end
1014
+
1015
+ context "keywords" do
1016
+ before(:each) do
1017
+ subject.set_mapping("id", "@id")
1018
+ subject.set_mapping("type", "@type")
1019
+ subject.set_mapping("list", "@list")
1020
+ subject.set_mapping("set", "@set")
1021
+ subject.set_mapping("language", "@language")
1022
+ subject.set_mapping("literal", "@value")
1023
+ end
1024
+
1025
+ {
1026
+ "@id" => [{"id" => "http://example.com/"}, {"@id" => "http://example.com/"}],
1027
+ "@type" => [{"literal" => "foo", "type" => "http://example.com/"},
1028
+ {"@value" => "foo", "@type" => "http://example.com/"}],
1029
+ "@value" => [{"literal" => "foo", "language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
1030
+ "@list" => [{"list" => ["foo"]}, {"@list" => ["foo"] }],
1031
+ "@set" => [{"set" => ["foo"]}, {"@set" => ["foo"] }],
1032
+ }.each do |title, (compacted, expanded)|
1033
+ it title do
1034
+ subject.compact_value("foo", expanded).should produce(compacted, @debug)
1035
+ end
1036
+ end
1037
+ end
1038
+ end
1039
+ end