json-ld 1.0.5 → 1.0.6

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.
@@ -8,25 +8,8 @@ describe JSON::LD do
8
8
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/compact-manifest.jsonld")
9
9
  describe m.name do
10
10
  m.entries.each do |t|
11
- specify "#{t.property('input')}: #{t.name}" do
12
- begin
13
- t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
14
- if t.property('context')
15
- t.debug << "context: #{t.context.read}"
16
- t.context.rewind
17
- end
18
- result = JSON::LD::API.compact(t.input, t.context,
19
- :base => t.base,
20
- :debug => t.debug)
21
- expected = JSON.load(t.expect)
22
- result.should produce(expected, t.debug)
23
- rescue JSON::LD::ProcessingError => e
24
- fail("Processing error: #{e.message}")
25
- rescue JSON::LD::InvalidContext => e
26
- fail("Invalid Context: #{e.message}")
27
- rescue JSON::LD::InvalidFrame => e
28
- fail("Invalid Frame: #{e.message}")
29
- end
11
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
12
+ t.run self
30
13
  end
31
14
  end
32
15
  end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ $:.unshift "."
3
+ require 'spec_helper'
4
+
5
+ describe JSON::LD do
6
+ describe "test suite" do
7
+ require 'suite_helper'
8
+ m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/error-manifest.jsonld")
9
+ describe m.name do
10
+ m.entries.each do |t|
11
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
12
+ t.run self
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end unless ENV['CI']
@@ -8,22 +8,8 @@ describe JSON::LD do
8
8
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/expand-manifest.jsonld")
9
9
  describe m.name do
10
10
  m.entries.each do |t|
11
- specify "#{t.property('input')}: #{t.name}" do
12
- begin
13
- t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
14
- t.debug << "context: #{t.context.read}" if t.property('context')
15
- result = JSON::LD::API.expand(t.input, nil,
16
- :base => t.base,
17
- :debug => t.debug)
18
- expected = JSON.load(t.expect)
19
- result.should produce(expected, t.debug)
20
- rescue JSON::LD::ProcessingError => e
21
- fail("Processing error: #{e.message}")
22
- rescue JSON::LD::InvalidContext => e
23
- fail("Invalid Context: #{e.message}")
24
- rescue JSON::LD::InvalidFrame => e
25
- fail("Invalid Frame: #{e.message}")
26
- end
11
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
12
+ t.run self
27
13
  end
28
14
  end
29
15
  end
@@ -9,22 +9,8 @@ describe JSON::LD do
9
9
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/flatten-manifest.jsonld")
10
10
  describe m.name do
11
11
  m.entries.each do |t|
12
- specify "#{t.property('input')}: #{t.name}" do
13
- begin
14
- t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
15
- t.debug << "frame: #{t.frame.read}" if t.property('frame')
16
- result = JSON::LD::API.flatten(t.input, t.context,
17
- :base => t.base,
18
- :debug => t.debug)
19
- expected = JSON.load(t.expect)
20
- result.should produce(expected, t.debug)
21
- rescue JSON::LD::ProcessingError => e
22
- fail("Processing error: #{e.message}")
23
- rescue JSON::LD::InvalidContext => e
24
- fail("Invalid Context: #{e.message}")
25
- rescue JSON::LD::InvalidFrame => e
26
- fail("Invalid Frame: #{e.message}")
27
- end
12
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
13
+ t.run self
28
14
  end
29
15
  end
30
16
  end
@@ -9,22 +9,8 @@ describe JSON::LD do
9
9
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/frame-manifest.jsonld")
10
10
  describe m.name do
11
11
  m.entries.each do |t|
12
- specify "#{t.property('input')}: #{t.name}" do
13
- begin
14
- t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
15
- t.debug << "frame: #{t.frame.read}" if t.property('frame')
16
- result = JSON::LD::API.frame(t.input, t.frame,
17
- :base => t.base,
18
- :debug => t.debug)
19
- expected = JSON.load(t.expect)
20
- result.should produce(expected, t.debug)
21
- rescue JSON::LD::ProcessingError => e
22
- fail("Processing error: #{e.message}\n#{t.debug.join("\n")}\n#{e.backtrace.join("\n")}}")
23
- rescue JSON::LD::InvalidContext => e
24
- fail("Invalid Context: #{e.message}\n#{t.debug.join("\n")}\n#{e.backtrace.join("\n")}}")
25
- rescue JSON::LD::InvalidFrame => e
26
- fail("Invalid Frame: #{e.message}\n#{t.debug.join("\n")}\n#{e.backtrace.join("\n")}}")
27
- end
12
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
13
+ t.run self
28
14
  end
29
15
  end
30
16
  end
@@ -8,24 +8,8 @@ describe JSON::LD do
8
8
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/fromRdf-manifest.jsonld")
9
9
  describe m.name do
10
10
  m.entries.each do |t|
11
- specify "#{t.property('input')}: #{t.name}" do
12
- begin
13
- t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
14
- t.input.rewind
15
- t.debug << "result: #{t.expect.read}"
16
- repo = RDF::Repository.load(t.base)
17
- t.debug << "repo: #{repo.dump(t.id == '#t0012' ? :nquads : :trig)}"
18
- result = JSON::LD::API.fromRDF(repo.each_statement.to_a,
19
- :debug => t.debug)
20
- expected = JSON.load(t.expect)
21
- result.should produce(expected, t.debug)
22
- rescue JSON::LD::ProcessingError => e
23
- fail("Processing error: #{e.message}")
24
- rescue JSON::LD::InvalidContext => e
25
- fail("Invalid Context: #{e.message}")
26
- rescue JSON::LD::InvalidFrame => e
27
- fail("Invalid Frame: #{e.message}")
28
- end
11
+ specify "#{t.property('input')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
12
+ t.run self
29
13
  end
30
14
  end
31
15
  end
@@ -2,65 +2,10 @@ require 'json/ld'
2
2
  require 'open-uri'
3
3
  require 'support/extensions'
4
4
 
5
- # For now, override RDF::Utils::File.open_file to look for the file locally before attempting to retrieve it
6
- module RDF::Util
7
- module File
8
- REMOTE_PATH = "http://json-ld.org/test-suite/"
9
- LOCAL_PATH = ::File.expand_path("../json-ld.org/test-suite", __FILE__) + '/'
10
-
11
- ##
12
- # Override to use Patron for http and https, Kernel.open otherwise.
13
- #
14
- # @param [String] filename_or_url to open
15
- # @param [Hash{Symbol => Object}] options
16
- # @option options [Array, String] :headers
17
- # HTTP Request headers.
18
- # @return [IO] File stream
19
- # @yield [IO] File stream
20
- def self.open_file(filename_or_url, options = {}, &block)
21
- case filename_or_url.to_s
22
- when /^file:/
23
- path = filename_or_url[5..-1]
24
- Kernel.open(path.to_s, &block)
25
- when /^#{REMOTE_PATH}/
26
- begin
27
- #puts "attempt to open #{filename_or_url} locally"
28
- local_filename = filename_or_url.to_s.sub(REMOTE_PATH, LOCAL_PATH)
29
- if ::File.exist?(local_filename)
30
- response = ::File.open(local_filename)
31
- #puts "use #{filename_or_url} locally"
32
- case filename_or_url.to_s
33
- when /\.jsonld$/
34
- def response.content_type; 'application/ld+json'; end
35
- when /\.sparql$/
36
- def response.content_type; 'application/sparql-query'; end
37
- end
38
-
39
- if block_given?
40
- begin
41
- yield response
42
- ensure
43
- response.close
44
- end
45
- else
46
- response
47
- end
48
- else
49
- Kernel.open(filename_or_url.to_s, &block)
50
- end
51
- rescue Errno::ENOENT #, OpenURI::HTTPError
52
- # Not there, don't run tests
53
- StringIO.new("")
54
- end
55
- end
56
- end
57
- end
58
- end
59
-
60
5
  module Fixtures
61
6
  module SuiteTest
62
7
  SUITE = RDF::URI("http://json-ld.org/test-suite/")
63
- TEST_IRI_BASE = RDF::URI("http://example/").freeze
8
+ #SUITE = RDF::URI("http://localhost/~gregg/json-ld.org/test-suite/")
64
9
 
65
10
  class Manifest < JSON::LD::Resource
66
11
  def self.open(file)
@@ -94,16 +39,39 @@ module Fixtures
94
39
 
95
40
  # Base is expanded input file
96
41
  def base
97
- "#{SUITE}tests/#{property('input')}"
42
+ options.fetch('base', "#{SUITE}tests/#{property('input')}")
43
+ end
44
+
45
+ def options
46
+ @options ||= begin
47
+ opts = {:documentLoader => self.class.method(:documentLoader)}
48
+ {'processingMode' => "json-ld-1.0"}.merge(property('option') || {}).each do |k, v|
49
+ opts[k.to_sym] = v
50
+ end
51
+ opts
52
+ end
98
53
  end
99
54
 
100
55
  # Alias input, context, expect and frame
101
56
  %w(input context expect frame).each do |m|
102
- define_method(m.to_sym) {property(m) && RDF::Util::File.open_file("#{SUITE}tests/#{property(m)}")}
57
+ define_method(m.to_sym) do
58
+ return nil unless property(m)
59
+ res = nil
60
+ self.class.documentLoader("#{SUITE}tests/#{property(m)}", :safe => true) do |remote_doc|
61
+ res = remote_doc.document
62
+ end
63
+ res
64
+ end
65
+
66
+ define_method("#{m}_loc".to_sym) {property(m) && "#{SUITE}tests/#{property(m)}"}
103
67
  end
104
68
 
105
69
  def testType
106
- property('@type').reject {|t| t =~ /EvaluationTest/}.first
70
+ property('@type').reject {|t| t =~ /EvaluationTest|SyntaxTest/}.first
71
+ end
72
+
73
+ def evaluationTest?
74
+ property('@type').to_s.include?('EvaluationTest')
107
75
  end
108
76
 
109
77
  def positiveTest?
@@ -112,11 +80,103 @@ module Fixtures
112
80
 
113
81
  def trace; @debug.join("\n"); end
114
82
 
83
+ # Execute the test
84
+ def run(rspec_example = nil)
85
+ debug = ["test: #{inspect}", "source: #{input}"]
86
+ debug << "context: #{context}" if context_loc
87
+ debug << "options: #{options.inspect}" unless options.empty?
88
+ debug << "frame: #{frame}" if frame_loc
89
+
90
+ options = if self.options[:useDocumentLoader]
91
+ self.options.merge(:documentLoader => method(:documentLoader))
92
+ else
93
+ self.options.dup
94
+ end
95
+
96
+ if positiveTest?
97
+ debug << "expected: #{expect rescue nil}" if expect_loc
98
+ begin
99
+ result = case testType
100
+ when "jld:ExpandTest"
101
+ JSON::LD::API.expand(input_loc, options.merge(:debug => debug))
102
+ when "jld:CompactTest"
103
+ JSON::LD::API.compact(input_loc, context_loc, options.merge(:debug => debug))
104
+ when "jld:FlattenTest"
105
+ JSON::LD::API.flatten(input_loc, context_loc, options.merge(:debug => debug))
106
+ when "jld:FrameTest"
107
+ JSON::LD::API.frame(input_loc, frame_loc, options.merge(:debug => debug))
108
+ when "jld:FromRDFTest"
109
+ repo = RDF::Repository.load(input_loc, :format => :nquads)
110
+ debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
111
+ JSON::LD::API.fromRDF(repo, options.merge(:debug => debug))
112
+ when "jld:ToRDFTest"
113
+ JSON::LD::API.toRDF(input_loc, options.merge(:debug => debug)).map do |statement|
114
+ to_quad(statement)
115
+ end
116
+ else
117
+ fail("Unknown test type: #{testType}")
118
+ end
119
+ if evaluationTest?
120
+ if testType == "jld:ToRDFTest"
121
+ expected = expect
122
+ rspec_example.instance_eval {
123
+ expect(result.sort.join("")).to produce(expected, debug)
124
+ }
125
+ else
126
+ expected = JSON.load(expect)
127
+ rspec_example.instance_eval {
128
+ expect(result).to produce(expected, debug)
129
+ }
130
+ end
131
+ else
132
+ rspec_example.instance_eval {
133
+ expect(result).to_not be_nil
134
+ }
135
+ end
136
+ rescue JSON::LD::JsonLdError => e
137
+ fail("Processing error: #{e.message}")
138
+ rescue JSON::LD::InvalidFrame => e
139
+ fail("Invalid Frame: #{e.message}")
140
+ end
141
+ else
142
+ debug << "expected: #{property('expect')}" if property('expect')
143
+ t = self
144
+ rspec_example.instance_eval do
145
+ if t.evaluationTest?
146
+ expect do
147
+ case t.testType
148
+ when "jld:ExpandTest"
149
+ JSON::LD::API.expand(t.input_loc, options.merge(:debug => debug))
150
+ when "jld:CompactTest"
151
+ JSON::LD::API.compact(t.input_loc, t.context_loc, options.merge(:debug => debug))
152
+ when "jld:FlattenTest"
153
+ JSON::LD::API.flatten(t.input_loc, t.context_loc, options.merge(:debug => debug))
154
+ when "jld:FrameTest"
155
+ JSON::LD::API.frame(t.input_loc, t.frame_loc, options.merge(:debug => debug))
156
+ when "jld:FromRDFTest"
157
+ repo = RDF::Repository.load(t.input_loc)
158
+ debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
159
+ JSON::LD::API.fromRDF(repo, options.merge(:debug => debug))
160
+ when "jld:ToRDFTest"
161
+ JSON::LD::API.toRDF(t.input_loc, options.merge(:debug => debug)).map do |statement|
162
+ t.to_quad(statement)
163
+ end
164
+ else
165
+ success("Unknown test type: #{testType}")
166
+ end
167
+ end.to raise_error(/#{t.property('expect')}/)
168
+ else
169
+ fail("No support for NegativeSyntaxTest")
170
+ end
171
+ end
172
+ end
173
+ end
174
+
115
175
  # Don't use NQuads writer so that we don't escape Unicode
116
176
  def to_quad(thing)
117
177
  case thing
118
178
  when RDF::URI
119
- TEST_IRI_BASE.join(thing).canonicalize.to_ntriples
179
+ thing.canonicalize.to_ntriples
120
180
  when RDF::Node
121
181
  escaped(thing)
122
182
  when RDF::Literal::Double
@@ -150,6 +210,104 @@ module Fixtures
150
210
  string.to_s.gsub('\\', '\\\\').gsub("\t", '\\t').
151
211
  gsub("\n", '\\n').gsub("\r", '\\r').gsub('"', '\\"')
152
212
  end
213
+
214
+ REMOTE_PATH = "http://json-ld.org/test-suite/"
215
+ LOCAL_PATH = ::File.expand_path("../json-ld.org/test-suite", __FILE__) + '/'
216
+ ##
217
+ # Document loader to use for tests having `useDocumentLoader` option
218
+ #
219
+ # @param [RDF::URI, String] url
220
+ # @param [Hash<Symbol => Object>] options
221
+ # @option options [Boolean] :validate
222
+ # Allow only appropriate content types
223
+ # @return [RemoteDocument] retrieved remote document and context information unless block given
224
+ # @yield remote_document
225
+ # @yieldparam [RemoteDocument] remote_document
226
+ # @raise [JsonLdError]
227
+ def self.documentLoader(url, options = {})
228
+ require 'net/http' unless defined?(Net::HTTP)
229
+ remote_document = nil
230
+ options[:headers] ||= JSON::LD::API::OPEN_OPTS[:headers]
231
+
232
+ url = url.to_s[5..-1] if url.to_s.start_with?("file:")
233
+
234
+ if url.to_s.start_with?(REMOTE_PATH) && ::File.exist?(LOCAL_PATH) && url.to_s !~ /remote-doc/
235
+ #puts "attempt to open #{filename_or_url} locally"
236
+ local_filename = url.to_s.sub(REMOTE_PATH, LOCAL_PATH)
237
+ if ::File.exist?(local_filename)
238
+ remote_document = JSON::LD::API::RemoteDocument.new(url.to_s, ::File.read(local_filename))
239
+ yield remote_document if block_given?
240
+ else
241
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "no such file #{local_filename}"
242
+ end
243
+ return remote_document
244
+ end
245
+
246
+ case url.to_s
247
+ when /^http/
248
+ parsed_url = ::URI.parse(url.to_s)
249
+ until remote_document do
250
+ Net::HTTP::start(parsed_url.host, parsed_url.port) do |http|
251
+ request = Net::HTTP::Get.new(parsed_url.request_uri, options[:headers])
252
+ http.request(request) do |response|
253
+ case response
254
+ when Net::HTTPSuccess
255
+ # found object
256
+ content_type, ct_param = response.content_type.to_s.downcase.split(";")
257
+ if content_type && options[:validate]
258
+ main, sub = content_type.split("/")
259
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "content_type: #{content_type}" if
260
+ main != 'application' ||
261
+ sub !~ /^(.*\+)?json$/
262
+ end
263
+
264
+ remote_document = JSON::LD::API::RemoteDocument.new(parsed_url.to_s, response.body)
265
+
266
+ unless content_type.start_with?("application/ld+json")
267
+ links = response["link"].to_s.
268
+ split(",").
269
+ map(&:strip).
270
+ select {|h| h =~ %r{rel=\"http://www.w3.org/ns/json-ld#context\"}}
271
+ case links.length
272
+ when 0 then #nothing to do
273
+ when 1
274
+ remote_document.contextUrl = links.first.match(/<([^>]*)>/) && $1
275
+ else
276
+ raise JSON::LD::JsonLdError::MultipleContextLinkHeaders,
277
+ "expected at most 1 Link header with rel=jsonld:context, got #{links.length}"
278
+ end
279
+ end
280
+ yield remote_document if block_given?
281
+ when Net::HTTPRedirection
282
+ # Follow redirection
283
+ parsed_url = ::URI.parse(response["Location"])
284
+ else
285
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed,
286
+ "<#{parsed_url}>: #{response.msg}(#{response.code})"
287
+ end
288
+ end
289
+ end
290
+ end
291
+ else
292
+ # Use regular open
293
+ RDF::Util::File.open_file(url, options) do |f|
294
+ remote_document = JSON::LD::API::RemoteDocument.new(url, f.read)
295
+ content_type, ct_param = f.content_type.to_s.downcase.split(";") if f.respond_to?(:content_type)
296
+ if content_type && options[:validate]
297
+ main, sub = content_type.split("/")
298
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "content_type: #{content_type}" if
299
+ main != 'application' ||
300
+ sub !~ /^(.*\+)?json$/
301
+ end
302
+
303
+ yield remote_document if block_given?
304
+ end
305
+ end
306
+ remote_document
307
+ rescue JSON::LD::JsonLdError::LoadingDocumentFailed, JSON::LD::JsonLdError::MultipleContextLinkHeaders
308
+ raise unless options[:safe]
309
+ "don't raise error"
310
+ end
153
311
  end
154
312
  end
155
313
  end