json-ld 0.1.4.2 → 0.1.5

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/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