json-ld 0.3.2 → 0.9.0

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