json-ld 0.1.4.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.4.2
1
+ 0.1.5
@@ -47,6 +47,7 @@ module JSON
47
47
  @set
48
48
  @type
49
49
  @value
50
+ @vocab
50
51
  ).freeze
51
52
 
52
53
  # Regexp matching an NCName.
@@ -64,6 +64,14 @@ module JSON::LD
64
64
  # This adds a language to plain strings that aren't otherwise coerced
65
65
  # @attr [String]
66
66
  attr :default_language, true
67
+
68
+ # Default vocabulary
69
+ #
70
+ #
71
+ # Sets the default vocabulary used for expanding terms which
72
+ # aren't otherwise absolute IRIs
73
+ # @attr [String]
74
+ attr :vocab, true
67
75
 
68
76
  # Global options used in generating IRIs
69
77
  # @attr [Hash] options
@@ -149,8 +157,22 @@ module JSON::LD
149
157
  ec
150
158
  when Hash
151
159
  new_ec = self.dup
152
- new_ec.provided_context = context
153
-
160
+ new_ec.provided_context = context.dup
161
+
162
+ {
163
+ '@language' => :default_language=,
164
+ '@vocab' => :vocab=
165
+ }.each do |key, setter|
166
+ v = context.fetch(key, false)
167
+ if v.nil? || v.is_a?(String)
168
+ context.delete(key)
169
+ debug("parse") {"Hash[#{key}] = #{v.inspect}"}
170
+ new_ec.send(setter, v)
171
+ elsif v
172
+ raise InvalidContext::Syntax, "#{key.inspect} is invalid"
173
+ end
174
+ end
175
+
154
176
  num_updates = 1
155
177
  while num_updates > 0 do
156
178
  num_updates = 0
@@ -159,8 +181,9 @@ module JSON::LD
159
181
  context.each do |key, value|
160
182
  # Expand a string value, unless it matches a keyword
161
183
  debug("parse") {"Hash[#{key}] = #{value.inspect}"}
162
- if key == '@language' && (value.nil? || value.is_a?(String))
163
- new_ec.default_language = value
184
+
185
+ if KEYWORDS.include?(key)
186
+ raise InvalidContext::Syntax, "key #{key.inspect} must not be a keyword"
164
187
  elsif term_valid?(key)
165
188
  # Remove all coercion information for the property
166
189
  new_ec.set_coerce(key, nil)
@@ -172,9 +195,7 @@ module JSON::LD
172
195
  raise InvalidContext::Syntax, "unknown mapping for #{key.inspect} to #{value.class}" unless value.is_a?(String) || value.nil?
173
196
 
174
197
  iri = new_ec.expand_iri(value, :position => :predicate) if value.is_a?(String)
175
- if iri && KEYWORDS.include?(key)
176
- raise InvalidContext::Syntax, "key #{key.inspect} must not be a keyword"
177
- elsif iri && new_ec.mappings.fetch(key, nil) != iri
198
+ if iri && new_ec.mappings.fetch(key, nil) != iri
178
199
  # Record term definition
179
200
  new_ec.set_mapping(key, iri)
180
201
  num_updates += 1
@@ -254,6 +275,7 @@ module JSON::LD
254
275
  debug {"=> context: #{inspect}"}
255
276
  ctx = Hash.ordered
256
277
  ctx['@language'] = default_language.to_s if default_language
278
+ ctx['@vocab'] = vocab.to_s if vocab
257
279
 
258
280
  # Mappings
259
281
  mappings.keys.sort{|a, b| a.to_s <=> b.to_s}.each do |k|
@@ -453,7 +475,7 @@ module JSON::LD
453
475
  return iri unless iri.is_a?(String)
454
476
  prefix, suffix = iri.split(':', 2)
455
477
  return mapping(iri) if mapping(iri) # If it's an exact match
456
- debug("expand_iri") {"prefix: #{prefix.inspect}, suffix: #{suffix.inspect}"} unless options[:quiet]
478
+ debug("expand_iri") {"prefix: #{prefix.inspect}, suffix: #{suffix.inspect}, vocab: #{vocab.inspect}"} unless options[:quiet]
457
479
  base = self.base unless [:predicate, :datatype].include?(options[:position])
458
480
  prefix = prefix.to_s
459
481
  case
@@ -462,6 +484,7 @@ module JSON::LD
462
484
  when suffix.to_s[0,2] == '//' then uri(iri)
463
485
  when mappings.has_key?(prefix) then uri(mappings[prefix] + suffix.to_s)
464
486
  when base then base.join(iri)
487
+ when vocab then uri("#{vocab}#{iri}")
465
488
  else
466
489
  # Otherwise, it must be an absolute IRI
467
490
  u = uri(iri)
@@ -535,10 +558,20 @@ module JSON::LD
535
558
  least_distance = term_map.values.max
536
559
  terms = term_map.keys.select {|t| term_map[t] == least_distance}
537
560
 
538
- # If the list of found terms is empty, append a compact IRI for
539
- # each term which is a prefix of iri which does not have
540
- # @type coercion, @container coercion or @language coercion rules
541
- # along with the iri itself.
561
+ # If terms is empty, and the active context has a @vocab which is a
562
+ # prefix of iri where the resulting relative IRI is not a term in the
563
+ # active context. The resulting relative IRI is the unmatched part of iri.
564
+ if vocab && terms.empty? && iri.to_s.index(vocab) == 0
565
+ terms << iri.to_s.sub(vocab, '')
566
+ debug("vocab") {"vocab: #{vocab}, rel: #{terms.first}"}
567
+ end
568
+
569
+ # If terms is empty, add a compact IRI representation of iri for each
570
+ # term in the active context which maps to an IRI which is a prefix for
571
+ # iri where the resulting compact IRI is not a term in the active
572
+ # context. The resulting compact IRI is the term associated with the
573
+ # partially matched IRI in the active context concatenated with a colon
574
+ # (:) character and the unmatched part of iri.
542
575
  if terms.empty?
543
576
  debug("curies") {"mappings: #{mappings.inspect}"}
544
577
  curies = mappings.keys.map do |k|
@@ -566,20 +599,22 @@ module JSON::LD
566
599
  end
567
600
 
568
601
  debug("curies") {"selected #{terms.inspect}"}
602
+ end
569
603
 
570
- # If we still don't have any terms and we're using standard_prefixes,
571
- # try those, and add to mapping
572
- if terms.empty? && @options[:standard_prefixes]
573
- terms = RDF::Vocabulary.
574
- select {|v| iri.index(v.to_uri.to_s) == 0}.
575
- map do |v|
576
- prefix = v.__name__.to_s.split('::').last.downcase
577
- set_mapping(prefix, v.to_uri.to_s)
578
- iri.sub(v.to_uri.to_s, "#{prefix}:").sub(/:$/, '')
579
- end
580
- debug("curies") {"using standard prefies: #{terms.inspect}"}
581
- end
604
+ # If we still don't have any terms and we're using standard_prefixes,
605
+ # try those, and add to mapping
606
+ if terms.empty? && @options[:standard_prefixes]
607
+ terms = RDF::Vocabulary.
608
+ select {|v| iri.index(v.to_uri.to_s) == 0}.
609
+ map do |v|
610
+ prefix = v.__name__.to_s.split('::').last.downcase
611
+ set_mapping(prefix, v.to_uri.to_s)
612
+ iri.sub(v.to_uri.to_s, "#{prefix}:").sub(/:$/, '')
613
+ end
614
+ debug("curies") {"using standard prefies: #{terms.inspect}"}
615
+ end
582
616
 
617
+ if terms.empty?
583
618
  # If there is a mapping from the complete IRI to null, return null,
584
619
  # otherwise, return the complete IRI.
585
620
  if mappings.has_key?(iri.to_s) && !mapping(iri)
@@ -589,7 +624,7 @@ module JSON::LD
589
624
  terms << iri.to_s
590
625
  end
591
626
  end
592
-
627
+
593
628
  # Get the first term based on distance and lexecographical order
594
629
  # Prefer terms that don't have @container @set over other terms, unless as set is true
595
630
  terms = terms.sort do |a, b|
@@ -86,6 +86,12 @@ describe JSON::LD::EvaluationContext do
86
86
  }).default_language.should produce("en", @debug)
87
87
  end
88
88
 
89
+ it "extracts @vocab" do
90
+ subject.parse({
91
+ "@vocab" => "http://schema.org/"
92
+ }).vocab.should produce("http://schema.org/", @debug)
93
+ end
94
+
89
95
  it "maps term with IRI value" do
90
96
  subject.parse({
91
97
  "foo" => "http://example.com/"
@@ -154,6 +160,15 @@ describe JSON::LD::EvaluationContext do
154
160
  }, @debug)
155
161
  end
156
162
 
163
+ it "expands terms using @vocab" do
164
+ subject.parse({
165
+ "foo" => "bar",
166
+ "@vocab" => "http://example.com/"
167
+ }).mappings.should produce({
168
+ "foo" => "http://example.com/bar"
169
+ }, @debug)
170
+ end
171
+
157
172
  context "with null" do
158
173
  it "removes @language if set to null" do
159
174
  subject.parse([
@@ -166,6 +181,17 @@ describe JSON::LD::EvaluationContext do
166
181
  ]).default_language.should produce(nil, @debug)
167
182
  end
168
183
 
184
+ it "removes @vocab if set to null" do
185
+ subject.parse([
186
+ {
187
+ "@vocab" => "http://schema.org/"
188
+ },
189
+ {
190
+ "@vocab" => nil
191
+ }
192
+ ]).vocab.should produce(nil, @debug)
193
+ end
194
+
169
195
  it "loads initial context" do
170
196
  init_ec = JSON::LD::EvaluationContext.new
171
197
  nil_ec = subject.parse(nil)
@@ -197,6 +223,7 @@ describe JSON::LD::EvaluationContext do
197
223
  "@container as array" => {"foo" => {"@container" => []}},
198
224
  "@container as string" => {"foo" => {"@container" => "true"}},
199
225
  "@language as @id" => {"@language" => {"@id" => "http://example.com/"}},
226
+ "@vocab as @id" => {"@vocab" => {"@id" => "http://example.com/"}},
200
227
  }.each do |title, context|
201
228
  it title do
202
229
  lambda {
@@ -206,15 +233,15 @@ describe JSON::LD::EvaluationContext do
206
233
  end
207
234
  end
208
235
 
209
- (JSON::LD::KEYWORDS - %w(@language)).each do |kw|
210
- it "does not redefined #{kw} as a string" do
236
+ (JSON::LD::KEYWORDS - %w(@language @vocab)).each do |kw|
237
+ it "does not redefine #{kw} as a string" do
211
238
  lambda {
212
239
  ec = subject.parse({kw => "http://example.com/"})
213
240
  ec.serialize.should produce({}, @debug)
214
241
  }.should raise_error(JSON::LD::InvalidContext::Syntax)
215
242
  end
216
243
 
217
- it "does not redefined #{kw} with an @id" do
244
+ it "does not redefine #{kw} with an @id" do
218
245
  lambda {
219
246
  ec = subject.parse({kw => {"@id" => "http://example.com/"}})
220
247
  ec.serialize.should produce({}, @debug)
@@ -235,7 +262,7 @@ describe JSON::LD::EvaluationContext do
235
262
  end
236
263
 
237
264
  describe "#serialize" do
238
- it "uses provided context document" do
265
+ it "context document" do
239
266
  ctx = StringIO.new(@ctx_json)
240
267
  def ctx.content_type; "application/ld+json"; end
241
268
 
@@ -246,7 +273,7 @@ describe JSON::LD::EvaluationContext do
246
273
  }, @debug)
247
274
  end
248
275
 
249
- it "uses provided context array" do
276
+ it "context array" do
250
277
  ctx = [
251
278
  {"foo" => "http://example.com/"},
252
279
  {"baz" => "bob"}
@@ -258,7 +285,7 @@ describe JSON::LD::EvaluationContext do
258
285
  }, @debug)
259
286
  end
260
287
 
261
- it "uses provided context hash" do
288
+ it "context hash" do
262
289
  ctx = {"foo" => "http://example.com/"}
263
290
 
264
291
  ec = subject.parse(ctx)
@@ -276,6 +303,15 @@ describe JSON::LD::EvaluationContext do
276
303
  }, @debug)
277
304
  end
278
305
 
306
+ it "@vocab" do
307
+ subject.vocab = "http://example.com/"
308
+ subject.serialize.should produce({
309
+ "@context" => {
310
+ "@vocab" => "http://example.com/"
311
+ }
312
+ }, @debug)
313
+ end
314
+
279
315
  it "term mappings" do
280
316
  subject.set_mapping("foo", "http://example.com/")
281
317
  subject.serialize.should produce({
@@ -458,6 +494,18 @@ describe JSON::LD::EvaluationContext do
458
494
  }, @debug)
459
495
  end
460
496
 
497
+ it "compacts IRIs using @vocab" do
498
+ subject.vocab = 'http://example.org/'
499
+ subject.set_mapping("term", 'http://example.org/term')
500
+ subject.set_coerce("term", "http://example.org/datatype")
501
+ subject.serialize.should produce({
502
+ "@context" => {
503
+ "@vocab" => 'http://example.org/',
504
+ "term" => {"@id" => "term", "@type" => "datatype"}
505
+ }
506
+ }, @debug)
507
+ end
508
+
461
509
  context "extra keys or values" do
462
510
  {
463
511
  "extra key" => {
@@ -544,6 +592,33 @@ describe JSON::LD::EvaluationContext do
544
592
  end
545
593
  end
546
594
  end
595
+
596
+ context "@vocab" do
597
+ before(:each) { subject.vocab = "http://example.com/"}
598
+ {
599
+ :subject => false,
600
+ :predicate => true,
601
+ :object => false,
602
+ :datatype => true
603
+ }.each do |position, r|
604
+ context "as #{position}" do
605
+ {
606
+ "absolute IRI" => ["http://example.org/", "http://example.org/", true],
607
+ "term" => ["ex", "http://example.org/", true],
608
+ "prefix:suffix" => ["ex:suffix", "http://example.org/suffix", true],
609
+ "keyword" => ["@type", "@type", true],
610
+ "empty" => [":suffix", "http://empty/suffix", true],
611
+ "unmapped" => ["foo", "http://example.com/foo", true],
612
+ "empty term" => ["", "http://empty/", true],
613
+ }.each do |title, (input,result,abs)|
614
+ result = nil unless r || abs
615
+ it title do
616
+ subject.expand_iri(input).should produce(result, @debug)
617
+ end
618
+ end
619
+ end
620
+ end
621
+ end
547
622
  end
548
623
 
549
624
  describe "#compact_iri" do
@@ -568,6 +643,24 @@ describe JSON::LD::EvaluationContext do
568
643
  end
569
644
  end
570
645
 
646
+ context "with @vocab" do
647
+ before(:each) { subject.vocab = "http://example.org/"}
648
+
649
+ {
650
+ "absolute IRI" => ["http://example.com/", "http://example.com/"],
651
+ "term" => ["ex", "http://example.org/"],
652
+ "prefix:suffix" => ["suffix", "http://example.org/suffix"],
653
+ "keyword" => ["@type", "@type"],
654
+ "empty" => [":suffix", "http://empty/suffix"],
655
+ "unmapped" => ["foo", "foo"],
656
+ "bnode" => ["_:a", RDF::Node("a")],
657
+ }.each do |title, (result, input)|
658
+ it title do
659
+ subject.compact_iri(input).should produce(result, @debug)
660
+ end
661
+ end
662
+ end
663
+
571
664
  context "with value" do
572
665
  let(:ctx) do
573
666
  c = subject.parse({
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4.2
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-31 00:00:00.000000000 Z
12
+ date: 2012-08-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rdf