json-ld 0.3.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/json/ld/utils.rb CHANGED
@@ -36,7 +36,16 @@ module JSON::LD
36
36
  # @param [Object] value
37
37
  # @return [Boolean]
38
38
  def list?(value)
39
- value.is_a?(Hash) && value.keys == %w(@list)
39
+ value.is_a?(Hash) && value.has_key?('@list')
40
+ end
41
+
42
+ ##
43
+ # Is value annotated?
44
+ #
45
+ # @param [Object] value
46
+ # @return [Boolean]
47
+ def annotation?(value)
48
+ value.is_a?(Hash) && value.has_key?('@annotation')
40
49
  end
41
50
 
42
51
  ##
@@ -76,30 +85,52 @@ module JSON::LD
76
85
  ##
77
86
  # Utility class for mapping old blank node identifiers, or unnamed blank
78
87
  # nodes to new identifiers
79
- class BlankNodeNamer < Hash
88
+ class BlankNodeMapper < Hash
89
+ ##
90
+ # Just return a Blank Node based on `old`. Manufactures
91
+ # a node if `old` is nil or empty
92
+ # @param [String] old ("")
93
+ # @return [String]
94
+ def get_sym(old = "")
95
+ old = RDF::Node.new.to_s if old.to_s.empty?
96
+ old.to_s.sub(/_:/, '')
97
+ end
98
+
99
+ ##
100
+ # Get a new mapped name for `old`
101
+ #
102
+ # @param [String] old ("")
103
+ # @return [String]
104
+ def get_name(old = "")
105
+ "_:" + get_sym(old)
106
+ end
107
+ end
108
+
109
+ class BlankNodeNamer < BlankNodeMapper
80
110
  # @param [String] prefix
81
111
  def initialize(prefix)
82
- @prefix = "_:#{prefix}0"
112
+ @prefix = prefix.to_s
113
+ @num = 0
83
114
  super
84
115
  end
85
-
116
+
86
117
  ##
87
- # Get a new mapped name for `old`
88
- #
89
- # @param [String] old
118
+ # Get a new symbol mapped from `old`
119
+ # @param [String] old ("")
90
120
  # @return [String]
91
- def get_name(old)
121
+ def get_sym(old = "")
122
+ old = old.to_s.sub(/_:/, '')
92
123
  if old && self.has_key?(old)
93
124
  self[old]
94
- elsif old
95
- self[old] = @prefix.dup
96
- @prefix.succ!
97
- self[old]
125
+ elsif !old.empty?
126
+ @num += 1
127
+ #puts "allocate #{@prefix + (@num - 1).to_s} to #{old.inspect}"
128
+ self[old] = @prefix + (@num - 1).to_s
98
129
  else
99
130
  # Not referenced, just return a new unique value
100
- cur = @prefix.dup
101
- @prefix.succ!
102
- cur
131
+ @num += 1
132
+ #puts "allocate #{@prefix + (@num - 1).to_s} to #{old.inspect}"
133
+ @prefix + (@num - 1).to_s
103
134
  end
104
135
  end
105
136
  end
data/spec/compact_spec.rb CHANGED
@@ -58,7 +58,7 @@ describe JSON::LD::API do
58
58
  "@id" => {
59
59
  :input => {"@id" => "http://example.org/test#example"},
60
60
  :context => {},
61
- :output => {"@id" => "http://example.org/test#example"}
61
+ :output => {"@graph" => []}
62
62
  },
63
63
  "@id coercion" => {
64
64
  :input => {
@@ -280,7 +280,8 @@ describe JSON::LD::API do
280
280
  },
281
281
  "Uses subject alias" => {
282
282
  :input => [{
283
- "@id" => "http://example.com/id1"
283
+ "@id" => "http://example.com/id1",
284
+ "http://example.com/id1" => {"@value" => "foo", "@language" => "de"}
284
285
  }],
285
286
  :context => {
286
287
  "id1" => "http://example.com/id1",
@@ -292,104 +293,8 @@ describe JSON::LD::API do
292
293
  "@language" => "de"
293
294
  },
294
295
  "@id" => "id1",
296
+ "id1" => "foo"
295
297
  }
296
- },
297
- "Allows IRI to be aliased to null, but still output term using IRI" => {
298
- :context => {
299
- "http://example.com/comment" => nil,
300
- "comment_en" => {"@id" => "http://example.com/comment", "@language" => "en"}
301
- },
302
- :input => [{
303
- "http://example.com/comment" => [
304
- {"@value" => "comment in english", "@language" => "en"},
305
- {"@value" => "commentar auf deutsch", "@language" => "de"},
306
- {"@value" => "日本語でのコメント", "@language" => "ja"},
307
- ]
308
- }],
309
- :output => {
310
- "@context" => {
311
- "http://example.com/comment" => nil,
312
- "comment_en" => {"@id" => "http://example.com/comment", "@language" => "en"}
313
- },
314
- "comment_en" => "comment in english",
315
- }
316
- },
317
- "compact-0018" => {
318
- :context => %{{
319
- "id1": "http://example.com/id1",
320
- "type1": "http://example.com/t1",
321
- "type2": "http://example.com/t2",
322
- "@language": "de",
323
- "term": { "@id": "http://example.com/term" },
324
- "term1": { "@id": "http://example.com/term", "@container": "@list" },
325
- "term2": { "@id": "http://example.com/term", "@container": "@list", "@language": "en" }
326
- }},
327
- :input => %{{
328
- "http://example.com/term": [
329
- {
330
- "@list": [
331
- { "@value": "v1.1", "@language": "de" },
332
- { "@value": "v1.2", "@language": "de" },
333
- { "@value": "v1.3", "@language": "de" },
334
- 4,
335
- { "@value": "v1.5", "@language": "de" },
336
- { "@value": "v1.6", "@language": "en" }
337
- ]
338
- },
339
- {
340
- "@list": [
341
- { "@value": "v2.1", "@language": "en" },
342
- { "@value": "v2.2", "@language": "en" },
343
- { "@value": "v2.3", "@language": "en" },
344
- 4,
345
- { "@value": "v2.5", "@language": "en" },
346
- { "@value": "v2.6", "@language": "de" }
347
- ]
348
- }
349
- ]
350
- }},
351
- :output => %q{{
352
- "@context": {
353
- "id1": "http://example.com/id1",
354
- "type1": "http://example.com/t1",
355
- "type2": "http://example.com/t2",
356
- "@language": "de",
357
- "term": {
358
- "@id": "http://example.com/term"
359
- },
360
- "term1": {
361
- "@id": "http://example.com/term",
362
- "@container": "@list"
363
- },
364
- "term2": {
365
- "@id": "http://example.com/term",
366
- "@container": "@list",
367
- "@language": "en"
368
- }
369
- },
370
- "term1": [
371
- "v1.1",
372
- "v1.2",
373
- "v1.3",
374
- 4,
375
- "v1.5",
376
- {
377
- "@value": "v1.6",
378
- "@language": "en"
379
- }
380
- ],
381
- "term2": [
382
- "v2.1",
383
- "v2.2",
384
- "v2.3",
385
- 4,
386
- "v2.5",
387
- {
388
- "@value": "v2.6",
389
- "@language": "de"
390
- }
391
- ]
392
- }}
393
298
  }
394
299
  }.each_pair do |title, params|
395
300
  it title do
@@ -467,6 +372,132 @@ describe JSON::LD::API do
467
372
  end
468
373
  end
469
374
 
375
+ context "language maps" do
376
+ {
377
+ "compact-0024" => {
378
+ :input => [
379
+ {
380
+ "@id" => "http://example.com/queen",
381
+ "http://example.com/vocab/label" => [
382
+ {"@value" => "The Queen", "@language" => "en"},
383
+ {"@value" => "Die Königin", "@language" => "de"},
384
+ {"@value" => "Ihre Majestät", "@language" => "de"}
385
+ ]
386
+ }
387
+ ],
388
+ :context => {
389
+ "vocab" => "http://example.com/vocab/",
390
+ "label" => {"@id" => "vocab:label", "@container" => "@language"}
391
+ },
392
+ :output => {
393
+ "@context" => {
394
+ "vocab" => "http://example.com/vocab/",
395
+ "label" => {"@id" => "vocab:label", "@container" => "@language"}
396
+ },
397
+ "@id" => "http://example.com/queen",
398
+ "label" => {
399
+ "en" => "The Queen",
400
+ "de" => ["Die Königin", "Ihre Majestät"]
401
+ }
402
+ }
403
+ },
404
+ }.each_pair do |title, params|
405
+ it title do
406
+ jld = JSON::LD::API.compact(params[:input], params[:context], nil, :debug => @debug)
407
+ jld.should produce(params[:output], @debug)
408
+ end
409
+ end
410
+ end
411
+
412
+ context "property generators" do
413
+ {
414
+ "exactly matching" => {
415
+ :input => [{
416
+ "http://example.com/foo" => [{"@value" => "baz"}],
417
+ "http://example.com/bar"=> [{"@value" => "baz"}],
418
+ }],
419
+ :context => {
420
+ "foobar" => {"@id" => ["http://example.com/foo", "http://example.com/bar"]}
421
+ },
422
+ :output => {
423
+ "@context" => {
424
+ "foobar" => {"@id" => ["http://example.com/foo", "http://example.com/bar"]}
425
+ },
426
+ "foobar" => "baz"
427
+ }
428
+ },
429
+ "overlapping" => {
430
+ :input => [{
431
+ "http://example.com/foo" => [{"@value" => "baz"}, {"@value" => "baz1"}],
432
+ "http://example.com/bar"=> [{"@value" => "baz"}, {"@value" => "baz2"}],
433
+ }],
434
+ :context => {
435
+ "foobar" => {"@id" => ["http://example.com/foo", "http://example.com/bar"]}
436
+ },
437
+ :output => {
438
+ "@context" => {
439
+ "foobar" => {"@id" => ["http://example.com/foo", "http://example.com/bar"]}
440
+ },
441
+ "foobar" => "baz",
442
+ "http://example.com/foo" => "baz1",
443
+ "http://example.com/bar" => "baz2"
444
+ }
445
+ },
446
+ "compact-0031" => {
447
+ :input => JSON.parse(%q([{
448
+ "@id": "http://example.com/node/1",
449
+ "http://example.com/vocab/field_related": [{
450
+ "@id": "http://example.com/node/this-is-related-news"
451
+ }],
452
+ "http://schema.org/about": [{
453
+ "@id": "http://example.com/node/this-is-related-news"
454
+ }, {
455
+ "@id": "http://example.com/term/this-is-a-tag"
456
+ }],
457
+ "http://example.com/vocab/field_tags": [{
458
+ "@id": "http://example.com/term/this-is-a-tag"
459
+ }]
460
+ }])),
461
+ :context => JSON.parse(%q({
462
+ "site": "http://example.com/",
463
+ "field_tags": {
464
+ "@id": [ "site:vocab/field_tags", "http://schema.org/about" ],
465
+ "@container": "@set"
466
+ },
467
+ "field_related": {
468
+ "@id": [ "site:vocab/field_related", "http://schema.org/about" ]
469
+ }
470
+ })),
471
+ :output => JSON.parse(%q({
472
+ "@context": {
473
+ "site": "http://example.com/",
474
+ "field_tags": {
475
+ "@id": [
476
+ "site:vocab/field_tags",
477
+ "http://schema.org/about"
478
+ ],
479
+ "@container": "@set"
480
+ },
481
+ "field_related": {
482
+ "@id": [
483
+ "site:vocab/field_related",
484
+ "http://schema.org/about"
485
+ ]
486
+ }
487
+ },
488
+ "@id": "site:node/1",
489
+ "field_tags": [{"@id": "site:term/this-is-a-tag"}],
490
+ "field_related": {"@id": "site:node/this-is-related-news"}
491
+ })),
492
+ },
493
+ }.each_pair do |title, params|
494
+ it title do
495
+ jld = JSON::LD::API.compact(params[:input], params[:context], nil, :debug => @debug)
496
+ jld.should produce(params[:output], @debug)
497
+ end
498
+ end
499
+ end
500
+
470
501
  context "@graph" do
471
502
  {
472
503
  "Uses @graph given mutliple inputs" => {
@@ -483,20 +514,6 @@ describe JSON::LD::API do
483
514
  ]
484
515
  }
485
516
  },
486
- "Uses expanded node definitions for node references" => {
487
- :input => [
488
- {"@id" => "http://example.com/foo"},
489
- {"@id" => "http://example.com/bar"}
490
- ],
491
- :context => {"ex" => "http://example.com/"},
492
- :output => {
493
- "@context" => {"ex" => "http://example.com/"},
494
- "@graph" => [
495
- {"@id" => "ex:foo"},
496
- {"@id" => "ex:bar"}
497
- ]
498
- }
499
- },
500
517
  }.each_pair do |title, params|
501
518
  it title do
502
519
  jld = JSON::LD::API.compact(params[:input], params[:context], nil, :debug => @debug)
@@ -45,9 +45,8 @@ describe JSON::LD::EvaluationContext do
45
45
  }, @debug)
46
46
  end
47
47
 
48
- it "allows a non-existing @context" do
49
- ec = subject.parse(StringIO.new("{}"))
50
- ec.mappings.should produce({}, @debug)
48
+ it "notes non-existing @context" do
49
+ lambda {subject.parse(StringIO.new("{}"))}.should raise_error
51
50
  end
52
51
 
53
52
  it "parses a referenced context at a relative URI" do
@@ -204,6 +203,15 @@ describe JSON::LD::EvaluationContext do
204
203
  ]).vocab.should produce(nil, @debug)
205
204
  end
206
205
 
206
+ it "removes term if set to null with @vocab" do
207
+ subject.parse([
208
+ {
209
+ "@vocab" => "http://schema.org/",
210
+ "term" => nil
211
+ }
212
+ ]).mappings.should produce({"term" => nil}, @debug)
213
+ end
214
+
207
215
  it "loads initial context" do
208
216
  init_ec = JSON::LD::EvaluationContext.new
209
217
  nil_ec = subject.parse(nil)
@@ -218,6 +226,25 @@ describe JSON::LD::EvaluationContext do
218
226
  subject.parse({"name" => nil}).mapping("name").should be_nil
219
227
  end
220
228
  end
229
+
230
+ context "property generator" do
231
+ {
232
+ "empty" => [
233
+ {"term" => {"@id" => []}},
234
+ []
235
+ ],
236
+ "single" => [
237
+ {"term" => {"@id" => ["http://example.com/"]}},
238
+ ["http://example.com/"]
239
+ ],
240
+ "multiple" => [
241
+ {"term" => {"@id" => ["http://example.com/", "http://example.org/"]}},
242
+ ["http://example.com/", "http://example.org/"]
243
+ ],
244
+ }.each do |title, (input, result)|
245
+ specify(title) {subject.parse(input).mapping("term").should produce(result, @debug)}
246
+ end
247
+ end
221
248
  end
222
249
 
223
250
  describe "Syntax Errors" do
@@ -226,7 +253,8 @@ describe JSON::LD::EvaluationContext do
226
253
  "no @id, @type, or @container" => {"foo" => {}},
227
254
  "value as array" => {"foo" => []},
228
255
  "@id as object" => {"foo" => {"@id" => {}}},
229
- "@id as array" => {"foo" => {"@id" => []}},
256
+ "@id as array of object" => {"foo" => {"@id" => [{}]}},
257
+ "@id as array of null" => {"foo" => {"@id" => [nil]}},
230
258
  "@type as object" => {"foo" => {"@type" => {}}},
231
259
  "@type as array" => {"foo" => {"@type" => []}},
232
260
  "@type as @list" => {"foo" => {"@type" => "@list"}},
@@ -333,6 +361,15 @@ describe JSON::LD::EvaluationContext do
333
361
  }, @debug)
334
362
  end
335
363
 
364
+ it "property generator" do
365
+ subject.set_mapping("foo", ["http://example.com/", "http://example.org/"])
366
+ subject.serialize.should produce({
367
+ "@context" => {
368
+ "foo" => ["http://example.com/", "http://example.org/"]
369
+ }
370
+ }, @debug)
371
+ end
372
+
336
373
  it "@type with dependent prefixes in a single context" do
337
374
  subject.set_mapping("xsd", RDF::XSD.to_uri.to_s)
338
375
  subject.set_mapping("homepage", RDF::FOAF.homepage.to_s)
@@ -545,6 +582,15 @@ describe JSON::LD::EvaluationContext do
545
582
  subject.expand_iri("_:a").should be_a(RDF::Node)
546
583
  end
547
584
 
585
+ context "keywords" do
586
+ %w(id type).each do |kw|
587
+ it "expands #{kw} to @#{kw}" do
588
+ subject.set_mapping(kw, "@#{kw}")
589
+ subject.expand_iri(kw).should produce("@#{kw}", @debug)
590
+ end
591
+ end
592
+ end
593
+
548
594
  context "relative IRI" do
549
595
  {
550
596
  :subject => true,
@@ -579,7 +625,7 @@ describe JSON::LD::EvaluationContext do
579
625
  {
580
626
  :subject => true,
581
627
  :predicate => false,
582
- :type => false
628
+ :type => true
583
629
  }.each do |position, r|
584
630
  context "as #{position}" do
585
631
  before(:each) do
@@ -627,6 +673,23 @@ describe JSON::LD::EvaluationContext do
627
673
  end
628
674
  end
629
675
  end
676
+
677
+ it "removes term if set to null with @vocab" do
678
+ subject.set_mapping("term", nil)
679
+ subject.expand_iri("term").should produce(nil, @debug)
680
+ end
681
+ end
682
+
683
+ context "property generator" do
684
+ before(:each) {subject.set_mapping("pg", ["http://a/", "http://b/"])}
685
+ {
686
+ "term" => ["pg", ["http://a/", "http://b/"]],
687
+ "prefix:suffix" => ["pg:suffix", ["http://a/suffix", "http://b/suffix"]],
688
+ }.each do |title, (input,result)|
689
+ it title do
690
+ subject.expand_iri(input).should produce(result, @debug)
691
+ end
692
+ end
630
693
  end
631
694
  end
632
695
 
@@ -651,14 +714,14 @@ describe JSON::LD::EvaluationContext do
651
714
  subject.compact_iri(input).should produce(result, @debug)
652
715
  end
653
716
  end
654
-
717
+
655
718
  context "with @vocab" do
656
719
  before(:each) { subject.vocab = "http://example.org/"}
657
720
 
658
721
  {
659
722
  "absolute IRI" => ["http://example.com/", "http://example.com/"],
660
723
  "term" => ["ex", "http://example.org/"],
661
- "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
724
+ "prefix:suffix" => ["ex:suffix", "http://example.org/suffix"],
662
725
  "keyword" => ["@type", "@type"],
663
726
  "empty" => [":suffix", "http://empty/suffix"],
664
727
  "unmapped" => ["foo", "foo"],
@@ -668,6 +731,13 @@ describe JSON::LD::EvaluationContext do
668
731
  subject.compact_iri(input).should produce(result, @debug)
669
732
  end
670
733
  end
734
+
735
+ it "does not use @vocab if it would collide with a term" do
736
+ subject.set_mapping("name", "http://xmlns.com/foaf/0.1/name")
737
+ subject.set_mapping("ex", nil)
738
+ subject.compact_iri("http://example.org/name", :position => :predicate).
739
+ should produce("http://example.org/name", @debug)
740
+ end
671
741
  end
672
742
 
673
743
  context "with value" do
@@ -695,24 +765,18 @@ describe JSON::LD::EvaluationContext do
695
765
  "setdouble" => {"@id" => "http://example.com/double", "@type" => "xsd:double", "@container" => "@set"},
696
766
  "setdate" => {"@id" => "http://example.com/date", "@type" => "xsd:date", "@container" => "@set"},
697
767
  "setid" => {"@id" => "http://example.com/id", "@type" => "@id", "@container" => "@set"},
768
+ "langmap" => {"@id" => "http://example.com/langmap", "@container" => "@language"},
698
769
  })
699
770
  @debug.clear
700
771
  c
701
772
  end
702
773
 
703
774
  {
704
- "setplain" => [
705
- {"@value" => "foo"},
706
- {"@value" => "de", "@language" => "de"},
707
- {"@value" => "other dt", "@language" => "http://example.com/other-datatype"}
708
- ],
709
- "setlang" => [{"@value" => "en", "@language" => "en"}],
710
- "setbool" => [{"@value" => true}, {"@value" => false}, {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
711
- "setinteger" => [{"@value" => 1}, {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
712
- "setdouble" => [{"@value" => 1.1}, {"@value" => "1", "@type" => RDF::XSD.double.to_s}],
713
- "setdate" => [{"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}],
775
+ "langmap" => [{"@value" => "en", "@language" => "en"}],
776
+ "plain" => [{"@value" => "foo"}],
777
+ "setplain" => [{"@value" => "foo", "@language" => "pl"}] # looks like langmap
714
778
  }.each do |prop, values|
715
- context "uses #{prop}", :pending => "does algorithm favor @set?" do
779
+ context "uses #{prop}" do
716
780
  values.each do |value|
717
781
  it "for #{value.inspect}" do
718
782
  ctx.compact_iri("http://example.com/#{prop.sub('set', '')}", :value => value).should produce(prop, @debug)
@@ -725,6 +789,7 @@ describe JSON::LD::EvaluationContext do
725
789
  {
726
790
  "listplain" => [
727
791
  [{"@value" => "foo"}],
792
+ [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => "baz"}],
728
793
  [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1}],
729
794
  [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => 1.1}],
730
795
  [{"@value" => "foo"}, {"@value" => "bar"}, {"@value" => true}],
@@ -748,6 +813,112 @@ describe JSON::LD::EvaluationContext do
748
813
  end
749
814
  end
750
815
 
816
+ context "compact-0018" do
817
+ let(:ctx) do
818
+ subject.parse(JSON.parse %({
819
+ "id1": "http://example.com/id1",
820
+ "type1": "http://example.com/t1",
821
+ "type2": "http://example.com/t2",
822
+ "@language": "de",
823
+ "term": {
824
+ "@id": "http://example.com/term"
825
+ },
826
+ "term1": {
827
+ "@id": "http://example.com/term",
828
+ "@container": "@list"
829
+ },
830
+ "term2": {
831
+ "@id": "http://example.com/term",
832
+ "@container": "@list",
833
+ "@language": "en"
834
+ },
835
+ "term3": {
836
+ "@id": "http://example.com/term",
837
+ "@container": "@list",
838
+ "@language": null
839
+ },
840
+ "term4": {
841
+ "@id": "http://example.com/term",
842
+ "@container": "@list",
843
+ "@type": "type1"
844
+ },
845
+ "term5": {
846
+ "@id": "http://example.com/term",
847
+ "@container": "@list",
848
+ "@type": "type2"
849
+ }
850
+ }))
851
+ end
852
+
853
+ {
854
+ "term" => [
855
+ '{ "@value": "v0.1", "@language": "de" }',
856
+ '{ "@value": "v0.2", "@language": "en" }',
857
+ '{ "@value": "v0.3"}',
858
+ '{ "@value": 4}',
859
+ '{ "@value": true}',
860
+ '{ "@value": false}'
861
+ ],
862
+ "term1" => %q({
863
+ "@list": [
864
+ { "@value": "v1.1", "@language": "de" },
865
+ { "@value": "v1.2", "@language": "en" },
866
+ { "@value": "v1.3"},
867
+ { "@value": 14},
868
+ { "@value": true},
869
+ { "@value": false}
870
+ ]
871
+ }),
872
+ "term2" => %q({
873
+ "@list": [
874
+ { "@value": "v2.1", "@language": "en" },
875
+ { "@value": "v2.2", "@language": "en" },
876
+ { "@value": "v2.3", "@language": "en" },
877
+ { "@value": "v2.4", "@language": "en" },
878
+ { "@value": "v2.5", "@language": "en" },
879
+ { "@value": "v2.6", "@language": "en" }
880
+ ]
881
+ }),
882
+ "term3" => %q({
883
+ "@list": [
884
+ { "@value": "v3.1"},
885
+ { "@value": "v3.2"},
886
+ { "@value": "v3.3"},
887
+ { "@value": "v3.4"},
888
+ { "@value": "v3.5"},
889
+ { "@value": "v3.6"}
890
+ ]
891
+ }),
892
+ "term4" => %q({
893
+ "@list": [
894
+ { "@value": "v4.1", "@type": "http://example.com/t1" },
895
+ { "@value": "v4.2", "@type": "http://example.com/t1" },
896
+ { "@value": "v4.3", "@type": "http://example.com/t1" },
897
+ { "@value": "v4.4", "@type": "http://example.com/t1" },
898
+ { "@value": "v4.5", "@type": "http://example.com/t1" },
899
+ { "@value": "v4.6", "@type": "http://example.com/t1" }
900
+ ]
901
+ }),
902
+ "term5" => %q({
903
+ "@list": [
904
+ { "@value": "v5.1", "@type": "http://example.com/t2" },
905
+ { "@value": "v5.2", "@type": "http://example.com/t2" },
906
+ { "@value": "v5.3", "@type": "http://example.com/t2" },
907
+ { "@value": "v5.4", "@type": "http://example.com/t2" },
908
+ { "@value": "v5.5", "@type": "http://example.com/t2" },
909
+ { "@value": "v5.6", "@type": "http://example.com/t2" }
910
+ ]
911
+ }),
912
+ }.each do |term, value|
913
+ [value].flatten.each do |v|
914
+ it "Uses #{term} for #{v}" do
915
+ ctx.compact_iri("http://example.com/term", :value => JSON.parse(v)).
916
+ should produce(term, @debug)
917
+ end
918
+ end
919
+ end
920
+ end
921
+
751
922
  context "compact-0020" do
752
923
  let(:ctx) do
753
924
  subject.parse({
@@ -773,6 +944,18 @@ describe JSON::LD::EvaluationContext do
773
944
  should produce("sub:id/1", @debug)
774
945
  end
775
946
  end
947
+
948
+ context "compact-0041" do
949
+ let(:ctx) do
950
+ subject.parse({"name" => {"@id" => "http://example.com/property", "@container" => "@list"}})
951
+ end
952
+ it "Does not use @list with @annotation" do
953
+ ctx.compact_iri("http://example.com/property", :value => {
954
+ "@list" => ["one item"],
955
+ "@annotation" => "an annotation"
956
+ }).should produce("http://example.com/property", @debug)
957
+ end
958
+ end
776
959
  end
777
960
 
778
961
  describe "#term_rank" do
@@ -842,7 +1025,7 @@ describe JSON::LD::EvaluationContext do
842
1025
  "double value" => {:value => {"@value" => 1.1}, :rank => 1},
843
1026
  "string value" => {:value => {"@value" => "foo"}, :rank => 0},
844
1027
  "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
845
- "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
1028
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 2},
846
1029
  "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
847
1030
  "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
848
1031
  "null" => {:value => nil, :rank => 3},
@@ -883,11 +1066,11 @@ describe JSON::LD::EvaluationContext do
883
1066
  "boolean value" => {:value => {"@value" => true}, :rank => 2},
884
1067
  "integer value" => {:value => {"@value" => 1}, :rank => 2},
885
1068
  "double value" => {:value => {"@value" => 1.1}, :rank => 2},
886
- "string value" => {:value => {"@value" => "foo"}, :rank => 0},
1069
+ "string value" => {:value => {"@value" => "foo"}, :rank => 2},
887
1070
  "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 1},
888
- "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
1071
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 2},
889
1072
  "id" => {:value => {"@id" => "http://example/id"}, :rank => 1},
890
- "value string" => {:value => {"@value" => "foo"}, :rank => 0},
1073
+ "value string" => {:value => {"@value" => "foo"}, :rank => 2},
891
1074
  "null" => {:value => nil, :rank => 3},
892
1075
  },
893
1076
  "boolean" => {
@@ -944,7 +1127,7 @@ describe JSON::LD::EvaluationContext do
944
1127
  "double value" => {:value => {"@value" => 1.1}, :rank => 1},
945
1128
  "string value" => {:value => {"@value" => "foo"}, :rank => 0},
946
1129
  "date" => {:value => {"@value" => "2012-04-17", "@type" => RDF::XSD.date.to_s}, :rank => 0},
947
- "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 3},
1130
+ "lang" => {:value => {"@value" => "apple", "@language" => "en"}, :rank => 2},
948
1131
  "other lang" => {:value => {"@value" => "apple", "@language" => "de"}, :rank => 0},
949
1132
  "id" => {:value => {"@id" => "http://example/id"}, :rank => 0},
950
1133
  "null" => {:value => nil, :rank => 3},
@@ -997,18 +1180,18 @@ describe JSON::LD::EvaluationContext do
997
1180
  })
998
1181
  end
999
1182
  {
1000
- "v1.1" => [{"@value" => "v1.1", "@language" => "de"}, 3, 0],
1001
- "v1.2" => [{"@value" => "v1.2", "@language" => "de"}, 3, 0],
1002
- "v1.3" => [{"@value" => "v1.3", "@language" => "de"}, 3, 0],
1183
+ "v1.1" => [{"@value" => "v1.1", "@language" => "de"}, 2, 0],
1184
+ "v1.2" => [{"@value" => "v1.2", "@language" => "de"}, 2, 0],
1185
+ "v1.3" => [{"@value" => "v1.3", "@language" => "de"}, 2, 0],
1003
1186
  "v1.4" => [{"@value" => 4}, 2, 1],
1004
- "v1.5" => [{"@value" => "v1.5", "@language" => "de"}, 3, 0],
1005
- "v1.6" => [{"@value" => "v1.6", "@language" => "en"}, 1, 3],
1006
- "v2.1" => [{"@value" => "v2.1", "@language" => "en"}, 1, 3],
1007
- "v2.2" => [{"@value" => "v2.2", "@language" => "en"}, 1, 3],
1008
- "v2.3" => [{"@value" => "v2.3", "@language" => "en"}, 1, 3],
1187
+ "v1.5" => [{"@value" => "v1.5", "@language" => "de"}, 2, 0],
1188
+ "v1.6" => [{"@value" => "v1.6", "@language" => "en"}, 1, 2],
1189
+ "v2.1" => [{"@value" => "v2.1", "@language" => "en"}, 1, 2],
1190
+ "v2.2" => [{"@value" => "v2.2", "@language" => "en"}, 1, 2],
1191
+ "v2.3" => [{"@value" => "v2.3", "@language" => "en"}, 1, 2],
1009
1192
  "v2.4" => [{"@value" => 4}, 2, 1],
1010
- "v2.5" => [{"@value" => "v2.5", "@language" => "en"}, 1, 3],
1011
- "v2.6" => [{"@value" => "v2.6", "@language" => "de"}, 3, 0],
1193
+ "v2.5" => [{"@value" => "v2.5", "@language" => "en"}, 1, 2],
1194
+ "v2.6" => [{"@value" => "v2.6", "@language" => "de"}, 2, 0],
1012
1195
  }.each do |label, (val, r1, r2)|
1013
1196
  context label do
1014
1197
  it "has rank #{r1} for term1" do
@@ -1033,6 +1216,7 @@ describe JSON::LD::EvaluationContext do
1033
1216
  subject.set_coerce("foaf:age", RDF::XSD.integer.to_s)
1034
1217
  subject.set_coerce("foaf:knows", "@id")
1035
1218
  subject.set_coerce("dc:created", RDF::XSD.date.to_s)
1219
+ subject.set_coerce("ex:integer", RDF::XSD.integer.to_s)
1036
1220
  subject.set_coerce("ex:double", RDF::XSD.double.to_s)
1037
1221
  subject.set_coerce("ex:boolean", RDF::XSD.boolean.to_s)
1038
1222
  end
@@ -1091,18 +1275,18 @@ describe JSON::LD::EvaluationContext do
1091
1275
  context "coercion" do
1092
1276
  before(:each) {subject.default_language = "en"}
1093
1277
  {
1094
- "boolean-boolean" => ["ex:boolean", true, {"@value" => true}],
1095
- "boolean-double" => ["ex:double", true, {"@value" => "true", "@type" => RDF::XSD.double.to_s}],
1096
- "boolean-int" => ["foaf:age", true, {"@value" => true}],
1097
- "double-boolean" => ["ex:boolean", 1.1, {"@value" => "1.1", "@type" => RDF::XSD.boolean.to_s}],
1098
- "double-double" => ["ex:double", 1.1, {"@value" => "1.1E0", "@type" => RDF::XSD.double.to_s}],
1099
- "double-int" => ["foaf:age", 1.1, {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
1100
- "int-boolean" => ["ex:boolean", 1, {"@value" => "1", "@type" => RDF::XSD.boolean.to_s}],
1101
- "int-double" => ["ex:double", 1, {"@value" => "1.0E0", "@type" => RDF::XSD.double.to_s}],
1102
- "int-int" => ["foaf:age", 1, {"@value" => 1}],
1278
+ "boolean-boolean" => ["ex:boolean", true, {"@value" => true, "@type" => RDF::XSD.boolean.to_s}],
1279
+ "boolean-integer" => ["ex:integer", true, {"@value" => true, "@type" => RDF::XSD.integer.to_s}],
1280
+ "boolean-double" => ["ex:double", true, {"@value" => true, "@type" => RDF::XSD.double.to_s}],
1281
+ "double-boolean" => ["ex:boolean", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.boolean.to_s}],
1282
+ "double-double" => ["ex:double", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.double.to_s}],
1283
+ "double-integer" => ["foaf:age", 1.1, {"@value" => 1.1, "@type" => RDF::XSD.integer.to_s}],
1284
+ "integer-boolean" => ["ex:boolean", 1, {"@value" => 1, "@type" => RDF::XSD.boolean.to_s}],
1285
+ "integer-double" => ["ex:double", 1, {"@value" => 1, "@type" => RDF::XSD.double.to_s}],
1286
+ "integer-integer" => ["foaf:age", 1, {"@value" => 1, "@type" => RDF::XSD.integer.to_s}],
1103
1287
  "string-boolean" => ["ex:boolean", "foo", {"@value" => "foo", "@type" => RDF::XSD.boolean.to_s}],
1104
1288
  "string-double" => ["ex:double", "foo", {"@value" => "foo", "@type" => RDF::XSD.double.to_s}],
1105
- "string-int" => ["foaf:age", "foo", {"@value" => "foo", "@type" => RDF::XSD.integer.to_s}],
1289
+ "string-integer" => ["foaf:age", "foo", {"@value" => "foo", "@type" => RDF::XSD.integer.to_s}],
1106
1290
  }.each do |title, (key, compacted, expanded)|
1107
1291
  it title do
1108
1292
  subject.expand_value(key, compacted).should produce(expanded, @debug)
@@ -1124,6 +1308,8 @@ describe JSON::LD::EvaluationContext do
1124
1308
  subject.set_coerce("dc:created", RDF::XSD.date.to_s)
1125
1309
  subject.set_container("list", "@list")
1126
1310
  subject.set_language("nolang", nil)
1311
+ subject.set_mapping("langmap", "http://example.org/langmap")
1312
+ subject.set_container("langmap", "@language")
1127
1313
  end
1128
1314
 
1129
1315
  {
@@ -1158,6 +1344,7 @@ describe JSON::LD::EvaluationContext do
1158
1344
  "no lang" => ["foo", {"@value" => "foo" }, {"@value" => "foo"}],
1159
1345
  "same lang" => ["foo", "foo", {"@value" => "foo", "@language" => "en"}],
1160
1346
  "other lang" => ["foo", {"@value" => "foo", "@language" => "bar"}, {"@value" => "foo", "@language" => "bar"}],
1347
+ "langmap" => ["langmap", "en", {"@value" => "en", "@language" => "en"}],
1161
1348
  "no lang with @type coercion" => ["dc:created", {"@value" => "foo"}, {"@value" => "foo"}],
1162
1349
  "no lang with @id coercion" => ["foaf:knows", {"@value" => "foo"}, {"@value" => "foo"}],
1163
1350
  "no lang with @language=null" => ["nolang", "string", {"@value" => "string"}],