ruby-sesame 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ === 0.1.0 / 2008-12-02
2
+
3
+ * Initial beta release.
@@ -0,0 +1,10 @@
1
+ COPYING
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/ruby-sesame.rb
7
+ spec/live_spec.rb
8
+ spec/shared_ruby_sesame_spec.rb
9
+ spec/spec.opts
10
+ spec/spec_helper.rb
@@ -0,0 +1,27 @@
1
+ == ruby-sesame
2
+ A Ruby library to interact with OpenRDF.org's Sesame RDF framework via its REST interface.
3
+
4
+ == Authors
5
+
6
+ Paul Legato (pjlegato at gmail dot com)
7
+
8
+
9
+ == LICENSE:
10
+
11
+ Copyright (C) 2008 Paul Legato (pjlegato at gmail dot com).
12
+
13
+ This file is part of Ruby-Sesame.
14
+
15
+ Ruby-Sesame is free software: you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License as published by
17
+ the Free Software Foundation, either version 3 of the License, or
18
+ (at your option) any later version.
19
+
20
+ Ruby-Sesame is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with Ruby-Sesame. If not, see <http://www.gnu.org/licenses/>.
27
+
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require 'lib/ruby-sesame'
4
+ require 'spec/rake/spectask'
5
+
6
+ Hoe.new('ruby-sesame', RubySesame::Version) do |p|
7
+ p.rubyforge_name = 'ruby-sesame'
8
+ p.author = 'Paul Legato'
9
+ p.summary = 'A Ruby interface to OpenRDF.org\'s Sesame RDF triple store'
10
+ p.email = 'pjlegato at gmail dot com'
11
+ p.url = 'http://ruby-sesame.rubyforge.org'
12
+ p.remote_rdoc_dir = '' # Release to root
13
+ end
14
+
15
+
16
+ desc "Run all specs"
17
+ Spec::Rake::SpecTask.new do |t|
18
+ t.spec_files = FileList["spec/*_spec.rb"].sort
19
+ t.spec_opts = ["--options", "spec/spec.opts"]
20
+ end
21
+
22
+ desc "Run all specs and get coverage statistics"
23
+ Spec::Rake::SpecTask.new('coverage') do |t|
24
+ t.spec_opts = ["--options", "spec/spec.opts"]
25
+ t.spec_files = FileList["spec/*_spec.rb"].sort
26
+ t.rcov_opts = ["--exclude", "spec", "--exclude", "gems"]
27
+ t.rcov = true
28
+ end
29
+
30
+ task :default => :spec
@@ -0,0 +1,346 @@
1
+ # Ruby-Sesame: a Ruby library to interact with OpenRDF.org's Sesame RDF
2
+ # framework via its REST interface.
3
+ #
4
+ # Copyright (C) 2008 Paul Legato (pjlegato at gmail dot com).
5
+ #
6
+ # This file is part of Ruby-Sesame.
7
+ #
8
+ # Ruby-Sesame is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ruby-Sesame is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ruby-Sesame. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require 'curb'
22
+ require 'json'
23
+
24
+ # Curb is faster, but doesn't do DELETE or PUT
25
+ require 'net/http'
26
+ require 'uri'
27
+
28
+ module RubySesame
29
+
30
+ Version = "0.1.0"
31
+
32
+ ## MIME types for result format to be sent by server.
33
+ DATA_TYPES = {
34
+ ## MIME types for variable binding formats
35
+ :XML => "application/sparql-results+xml",
36
+ :JSON => "application/sparql-results+json",
37
+ :binary => "application/x-binary-rdf-results-table",
38
+
39
+ ## MIME types for RDF formats
40
+ :RDFXML => "application/rdf+xml",
41
+ :NTriples => "text/plain",
42
+ :Turtle => "application/x-turtle",
43
+ :N3 => "text/rdf+n3",
44
+ :TriX => "application/trix",
45
+ :TriG => "application/x-trig",
46
+
47
+ ## MIME types for boolean result formats
48
+ # :XML type is valid here, too.
49
+ :PlainTextBoolean => "text/boolean"
50
+ }
51
+
52
+
53
+ class Server
54
+ attr_reader :url, :repositories
55
+
56
+ #
57
+ # Initialize a Server object at the given URL. Sesame uses a
58
+ # stateless REST protocol, so this will not actually do anything
59
+ # over the network unless query_server_information is true. Loads
60
+ # the protocol version and repositories available on the server if
61
+ # it is.
62
+ #
63
+ def initialize(url, query_server_information=false)
64
+ url = url + "/" unless url[-1..-1] == "/"
65
+ @url = url
66
+
67
+ if query_server_information
68
+ query_version
69
+ end
70
+ end # initialize
71
+
72
+
73
+ def query_version
74
+ @protocol_version = Curl::Easy.http_get(@url + "protocol").body_str.to_i
75
+ end
76
+
77
+ def protocol_version
78
+ @protocol_version || query_version
79
+ end
80
+
81
+ def repositories
82
+ @repositories || query_repositories
83
+ end
84
+
85
+ # Get a Repository by id. Returns the first repository if there is more than one.
86
+ def repository(id)
87
+ self.repositories.select {|r| r.id == id}.first
88
+ end
89
+
90
+ def query_repositories
91
+ easy = Curl::Easy.new
92
+ easy.headers["Accept"] = DATA_TYPES[:JSON]
93
+ easy.url = @url + "repositories"
94
+ easy.http_get
95
+ @repositories = JSON.parse(easy.body_str)["results"]["bindings"].map{|x| Repository.new(self, x) }
96
+ end
97
+
98
+ end # class Server
99
+
100
+ class Repository
101
+ attr_reader :server, :uri, :id, :title, :writable, :readable
102
+
103
+ def initialize(server, attrs)
104
+ @server = server
105
+ @uri = attrs["uri"]["value"]
106
+ @id = attrs["id"]["value"]
107
+ @title = attrs["title"]["value"]
108
+ @writable = attrs["writable"]["value"] == "true"
109
+ @readable = attrs["readable"]["value"] == "true"
110
+ end
111
+
112
+ #
113
+ # The valid result_types depend on what type of query you're
114
+ # doing: "Relevant values are the MIME types of supported RDF
115
+ # formats for graph queries, the MIME types of supported variable
116
+ # binding formats for tuple queries, and the MIME types of
117
+ # supported boolean result formats for boolean queries."
118
+ #
119
+ # Options:
120
+ #
121
+ # * :result_type - from DATA_TYPES
122
+ # * :method - :get or :post
123
+ # * :query_language - "sparql", "serql", or any other query language your Sesame server supports.
124
+ # * :infer => true or false. Defaults to true (serverside) if not specified.
125
+ # * :variable_bindings - if given, should be a Hash. If present, it will
126
+ # be used to bind variables outside the actual query. Keys are
127
+ # variable names and values are N-Triples encoded RDF values.
128
+
129
+ def query(query, options={})
130
+ options = {
131
+ :result_type => DATA_TYPES[:JSON],
132
+ :method => :get,
133
+ :query_language => "sparql",
134
+ }.merge(options)
135
+
136
+ easy = Curl::Easy.new
137
+ easy.headers["Accept"] = options[:result_type]
138
+
139
+ if options[:method] == :get
140
+ easy.url = (self.uri + "?" +
141
+ "query=#{ easy.escape(query) }&"+
142
+ "queryLn=#{ easy.escape(options[:query_language]) }&" +
143
+ (!options[:infer] ? "infer=false&" : "" ) +
144
+ if options[:variable_bindings]
145
+ options[:variable_bindings].keys.map {|name|
146
+ "$<#{ easy.escape(name) }>=#{ easy.escape(options[:variable_bindings][name]) }"
147
+ }.join("&")
148
+ else
149
+ ""
150
+ end
151
+ ).chop
152
+
153
+
154
+ easy.http_get
155
+
156
+ else # POST.
157
+ easy.url = self.uri
158
+
159
+ fields = ["query=#{ easy.escape(query) }",
160
+ "queryLn=#{ easy.escape(options[:query_language]) }"
161
+ ]
162
+
163
+ fields.push("infer=false") unless options[:infer]
164
+
165
+ options[:variable_bindings].keys.map {|name|
166
+ field.push("$<#{ easy.escape(name) }>=#{ easy.escape(options[:variable_bindings][name]) }")
167
+ } if options[:variable_bindings]
168
+
169
+ easy.http_post(fields)
170
+ end
171
+
172
+ easy.body_str
173
+ end # query
174
+
175
+ #
176
+ # Returns a list of statements from the repository (i.e. performs the REST GET operation on statements in the repository.)
177
+ #
178
+ # N.B. if unqualified with 1 or more options, this will return _all_ statements in the repository.
179
+ #
180
+ # Options:
181
+ #
182
+ # * result_type is the desired MIME type for results (see the DATA_TYPES constant.) Defaults to :Turtle.
183
+ #
184
+ # * 'subj' (optional): Restricts the GET to statements with the specified N-Triples encoded resource as subject.
185
+ # * 'pred' (optional): Restricts the GET to statements with the specified N-Triples encoded URI as predicate.
186
+ # * 'obj' (optional): Restricts the GET to statements with the specified N-Triples encoded value as object.
187
+ #
188
+ # * 'context' (optional): If specified, restricts the
189
+ # operation to one or more specific contexts in the
190
+ # repository. The value of this parameter is either an
191
+ # N-Triples encoded URI or bnode ID, or the special value
192
+ # 'null' which represents all context-less statements. If
193
+ # multiple 'context' parameters are specified as an Array, the request
194
+ # will operate on the union of all specified contexts. The
195
+ # operation is executed on all statements that are in the
196
+ # repository if no context is specified.
197
+ #
198
+ # * 'infer' (optional): Boolean; specifies whether inferred statements
199
+ # should be included in the result of GET requests. Inferred
200
+ # statements are included by default.
201
+ #
202
+ def get_statements(options={})
203
+ options = {:result_type => DATA_TYPES[:Turtle]}.merge(options)
204
+ easy = Curl::Easy.new
205
+ easy.headers["Accept"] = options[:result_type]
206
+
207
+ url = self.uri + "/statements?" + self.class.get_parameterize(options.reject{|k,v|
208
+ ![:subj, :pred, :obj, :context, :infer].include?(k)
209
+ })
210
+ easy.url = url
211
+ easy.http_get
212
+
213
+ easy.body_str
214
+ end # get_statements
215
+
216
+ # Delete one or more statements from the repository. Takes the same arguments as get_statements.
217
+ #
218
+ # If you do not set one of subj, pred, or obj in your options, it will delete ALL statements from the repository.
219
+ # This is ordinarily not allowed. Set safety=false to delete all statements.
220
+ #
221
+ def delete_statements!(options={}, safety=true)
222
+
223
+ unless !safety || options.keys.select {|x| [:subj, :pred, :obj].include?(x) }.size > 0
224
+ raise Exception.new("You asked to delete all statements in the repository. Either give a subj/pred/obj qualifier, or set safety=false")
225
+ end
226
+
227
+ # We have to use net/http, because curb has not yet implemented DELETE as of this writing.
228
+
229
+ uri = URI.parse(self.uri + "/statements?" + self.class.get_parameterize(options.reject{|k,v|
230
+ ![:subj, :pred, :obj, :context, :infer].include?(k)
231
+ }))
232
+ http = Net::HTTP.start(uri.host, uri.port)
233
+ http.delete(uri.path)
234
+ end # delete_statements!
235
+
236
+ # Convenience method; deletes all data from the repository.
237
+ def delete_all_statements!
238
+ delete_statements!({}, false)
239
+ end
240
+
241
+ # Returns the contexts available in the repository, unprocessed.
242
+ # Results are in JSON by default, though XML and binary are also available.
243
+ def raw_contexts(result_format="application/sparql-results+json")
244
+ easy = Curl::Easy.new
245
+ easy.headers["Accept"] = result_format
246
+
247
+ easy.url = self.uri + "/contexts"
248
+ easy.http_get
249
+ easy.body_str
250
+ end
251
+
252
+ # Returns an Array of Strings, where each is the id of a context available on the server.
253
+ def contexts
254
+ JSON.parse(raw_contexts())["results"]["bindings"].map{|x| x["contextID"]["value"] }
255
+ end
256
+
257
+ # Return the namespaces available in the repository, raw and unprocessed.
258
+ # Results are in JSON by default, though XML and binary are also available.
259
+ def raw_namespaces(result_format="application/sparql-results+json")
260
+ easy = Curl::Easy.new
261
+ easy.headers["Accept"] = result_format
262
+
263
+ easy.url = self.uri + "/namespaces"
264
+ easy.http_get
265
+ easy.body_str
266
+ end
267
+
268
+ # Returns a Hash. Keys are the prefixes, and the values are the corresponding namespaces.
269
+ def namespaces
270
+ ns = {}
271
+
272
+ JSON.parse(raw_namespaces)["results"]["bindings"].each {|x|
273
+ ns[x["prefix"]["value"]] = x["namespace"]["value"]
274
+ }
275
+ ns
276
+ end
277
+
278
+ # Gets the namespace for the given prefix.
279
+ # Returns nil if not found.
280
+ def namespace(prefix)
281
+ easy = Curl::Easy.new
282
+ easy.url = self.uri + "/namespaces/" + easy.escape(prefix)
283
+ easy.http_get
284
+ ns = easy.body_str
285
+ ns =~ /^Undefined prefix:/ ? nil : ns
286
+ end
287
+
288
+ # Sets the given prefix to the given namespace.
289
+ def namespace!(prefix, namespace)
290
+ uri = URI.parse(self.uri + "/namespaces/" + URI.escape(prefix))
291
+ http = Net::HTTP.start(uri.host, uri.port)
292
+ http.send_request('PUT', uri.path, namespace).body
293
+ end
294
+
295
+ # Deletes the namespace with the given prefix.
296
+ def delete_namespace!(prefix)
297
+ uri = URI.parse(self.uri + "/namespaces/" + URI.escape(prefix))
298
+ http = Net::HTTP.start(uri.host, uri.port)
299
+ http.delete(uri.path)
300
+ end
301
+
302
+ # Deletes all namespaces in the repository.
303
+ def delete_all_namespaces!
304
+ uri = URI.parse(self.uri + "/namespaces")
305
+ http = Net::HTTP.start(uri.host, uri.port)
306
+ http.delete(uri.path)
307
+ end
308
+
309
+
310
+ # Adds new data to the repository. The data can be an RDF document or a
311
+ # "special purpose transaction document". I don't know what the
312
+ # latter is.
313
+ def add!(data, data_format=DATA_TYPES[:Turtle])
314
+ easy = Curl::Easy.new
315
+ easy.headers["Content-Type"] = data_format
316
+
317
+ easy.url = self.uri + "/statements"
318
+ easy.http_post(data)
319
+ end # add
320
+
321
+
322
+ # Returns the number of statements in the repository.
323
+ def size
324
+ easy = Curl::Easy.new
325
+ easy.url = self.uri + "/size"
326
+ easy.http_get
327
+ easy.body_str.to_i
328
+ end
329
+
330
+
331
+ # Convert the given hash into an array of strings for a POST.
332
+ def self.post_parameterize(hash)
333
+ easy = Curl::Easy.new
334
+ hash.keys.map{|key|
335
+ easy.escape(key.to_s) + "=" + easy.escape(hash[key])
336
+ }
337
+ end
338
+
339
+ # Convert the given hash into a URL paramter string for a GET.
340
+ def self.get_parameterize(hash)
341
+ post_parameterize(hash).join("&")
342
+ end
343
+
344
+
345
+ end # class Repository
346
+ end
@@ -0,0 +1,273 @@
1
+ # Ruby-Sesame: a Ruby library to interact with OpenRDF.org's Sesame RDF
2
+ # framework via its REST interface.
3
+ #
4
+ # Copyright (C) 2008 Paul Legato (pjlegato at gmail dot com).
5
+ #
6
+ # This file is part of Ruby-Sesame.
7
+ #
8
+ # Ruby-Sesame is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ruby-Sesame is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ruby-Sesame. If not, see <http://www.gnu.org/licenses/>.
20
+ #
21
+ ####
22
+ ####
23
+ #
24
+ # This specifies the behavior when a live Sesame 2.0 server is running
25
+ # on localhost:8080 with the default configuration and a repository called "test".
26
+ #
27
+ # The contents of the "test" repository may be altered/erased by these tests.
28
+ #
29
+ # N.B. It will fail if that is not the case, through no fault of its own.
30
+ #
31
+
32
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
33
+
34
+ require 'xml/libxml'
35
+
36
+ URL = "http://localhost:8080/openrdf-sesame"
37
+
38
+ TUPLE_QUERY = <<END
39
+ PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
40
+ PREFIX sys:<http://www.openrdf.org/config/repository#>
41
+ SELECT ?id ?p ?o
42
+ WHERE {
43
+ ?id sys:repositoryID "SYSTEM" .
44
+ ?id ?p ?o .
45
+ }
46
+ END
47
+
48
+ GRAPH_QUERY = <<END
49
+ PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
50
+ PREFIX sys:<http://www.openrdf.org/config/repository#>
51
+ DESCRIBE ?id
52
+ WHERE {
53
+ ?id sys:repositoryID "SYSTEM" .
54
+ }
55
+ END
56
+
57
+ describe "Live Ruby-Sesame tests (**** N.B. these will fail unless you have a properly configured Sesame server running on localhost!)" do
58
+ it_should_behave_like "shared RubySesame specs"
59
+
60
+ before do
61
+ @server = RubySesame::Server.new(URL)
62
+ @system = @server.repository("SYSTEM")
63
+ @test = @server.repository("test")
64
+ end
65
+
66
+ it "should be able to query the Sesame server's version number" do
67
+ @server.protocol_version.should == 4
68
+ end
69
+
70
+ it "should be able to get a list of repositories" do
71
+ repos = nil
72
+ lambda { repos = @server.repositories }.should_not raise_error
73
+ repos.each {|r| r.class.should == RubySesame::Repository }
74
+ repos.select {|r| r.title == "System configuration repository" }.size.should == 1
75
+ repos.select {|r| r.id == "SYSTEM" }.size.should == 1
76
+ end
77
+
78
+ it "should auto-query upon initialization if told to do so" do
79
+ server = nil
80
+ lambda { server = RubySesame::Server.new(URL, true) }.should_not raise_error
81
+ server.protocol_version.should == 4
82
+ end
83
+
84
+ it "should be able to run a GET JSON tuple query on the System repository" do
85
+ result = nil
86
+
87
+ lambda { result = JSON.parse(@system.query(TUPLE_QUERY)) }.should_not raise_error
88
+ result["head"].should == { "vars" => ["id", "p", "o"] }
89
+ result["results"]["bindings"].size.should == 4
90
+
91
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "http://www.openrdf.org/config/repository#Repository"}.first["p"]["value"].should == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
92
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "SYSTEM"}.first["p"]["value"].should == "http://www.openrdf.org/config/repository#repositoryID"
93
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "System configuration repository"}.first["p"]["value"].should == "http://www.w3.org/2000/01/rdf-schema#label"
94
+ end
95
+
96
+ ## TODO: figure out how to verify that this actually does a POST and not a GET.
97
+ it "should be able to run a POST JSON tuple query on the System repository" do
98
+ result = nil
99
+
100
+ lambda { result = JSON.parse(@system.query(TUPLE_QUERY, :method => :post)) }.should_not raise_error
101
+
102
+ result["head"].should == { "vars" => ["id", "p", "o"] }
103
+ result["results"]["bindings"].size.should == 4
104
+
105
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "http://www.openrdf.org/config/repository#Repository"}.first["p"]["value"].should == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
106
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "SYSTEM"}.first["p"]["value"].should == "http://www.openrdf.org/config/repository#repositoryID"
107
+ result["results"]["bindings"].select{|x| x["o"]["value"] == "System configuration repository"}.first["p"]["value"].should == "http://www.w3.org/2000/01/rdf-schema#label"
108
+ end
109
+
110
+ it "should be able to get XML tuple results from the System repository" do
111
+ result = nil
112
+ lambda { result = @system.query(TUPLE_QUERY, :result_type => RubySesame::DATA_TYPES[:XML]) }.should_not raise_error
113
+
114
+ xml = nil
115
+ lambda { xml = XML::Parser.string(result).parse }
116
+ end
117
+
118
+ it "should be able to get binary tuple results from the System repository" do
119
+ result = nil
120
+ lambda { result = @system.query(TUPLE_QUERY, :result_type => RubySesame::DATA_TYPES[:binary]) }.should_not raise_error
121
+
122
+ result[0..3].should == "BRTR"
123
+ end
124
+
125
+ it "should be able to get RDFXML results for a graph query" do
126
+ result = nil
127
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:RDFXML]) }.should_not raise_error
128
+
129
+ xml = nil
130
+ lambda { xml = XML::Parser.string(result).parse }.should_not raise_error
131
+ end
132
+
133
+ it "should be able to get NTriples results for a graph query" do
134
+ result = nil
135
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:NTriples]) }.should_not raise_error
136
+ end
137
+
138
+ it "should be able to get Turtle results for a graph query" do
139
+ result = nil
140
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:Turtle]) }.should_not raise_error
141
+ end
142
+
143
+ it "should be able to get N3 results for a graph query" do
144
+ result = nil
145
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:N3]) }.should_not raise_error
146
+ end
147
+
148
+ it "should be able to get TriX results for a graph query" do
149
+ result = nil
150
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:TriX]) }.should_not raise_error
151
+ end
152
+
153
+ it "should be able to get TriG results for a graph query" do
154
+ result = nil
155
+ lambda { result = @system.query(GRAPH_QUERY, :result_type => RubySesame::DATA_TYPES[:TriG]) }.should_not raise_error
156
+ end
157
+
158
+ it "should be able to GET all statements with no arguments and Turtle-format results " do
159
+ result = nil
160
+ lambda { result = @system.get_statements() }.should_not raise_error
161
+ result.should =~ /^@prefix rdf: <http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#> .\n@prefix sys: <http:\/\/www.openrdf.org\/config\/repository#>/
162
+ end
163
+
164
+ it "should be able to GET all statements with RDFXML-format results " do
165
+ result = nil
166
+ lambda { result = @system.get_statements(:result_type => RubySesame::DATA_TYPES[:RDFXML]) }.should_not raise_error
167
+ result.should =~ /^#{Regexp.quote("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rdf:RDF\n\txmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"")}/
168
+ end
169
+
170
+ it "should be able to GET a subset of all statements by predicate" do
171
+ result = nil
172
+ # get a list of repository names
173
+ lambda { result = @system.get_statements(:pred => "<http://www.openrdf.org/config/repository#repositoryID>") }.should_not raise_error
174
+
175
+ result.should =~ /SYSTEM/
176
+ end
177
+
178
+ it "should be able to GET a subset of all statements by object" do
179
+ result = nil
180
+ # get a list of repository names
181
+ lambda { result = @system.get_statements(:obj => "<http://www.openrdf.org/config/repository#RepositoryContext>") }.should_not raise_error
182
+
183
+ result.should =~ / a /
184
+ end
185
+
186
+ it "should be able to get a list of contexts with at least 1 entry" do
187
+ c = @system.contexts
188
+ c.size.should >= 1
189
+ end
190
+
191
+ it "should be able to get a Hash of all namespaces from the repository" do
192
+ ns = nil
193
+ lambda { ns = @system.namespaces }.should_not raise_error
194
+ ns.should == {
195
+ "sys"=>"http://www.openrdf.org/config/repository#",
196
+ "rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
197
+ }
198
+ end
199
+
200
+ it "should be able to look up specific namespaces" do
201
+ @system.namespace("NonExistentNamespace").should == nil
202
+ @system.namespace("rdf").should == "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
203
+ @system.namespace("sys").should == "http://www.openrdf.org/config/repository#"
204
+ end
205
+
206
+ it "should be able to create and delete namespaces" do
207
+ @test.namespace("foo").should == nil
208
+
209
+ lambda { @test.namespace!("foo", "http://bar.baz/asdf") }.should_not raise_error
210
+ @test.namespace("foo").should == "http://bar.baz/asdf"
211
+
212
+ lambda { @test.delete_namespace!("foo") }.should_not raise_error
213
+ @test.namespace("foo").should == nil
214
+ end
215
+
216
+ it "should be able to delete all namespaces" do
217
+ lambda { @test.namespace!("foo", "http://bar.baz/asdf") }.should_not raise_error
218
+ lambda { @test.namespace!("bar", "http://bar.asdf.baz/asdf") }.should_not raise_error
219
+ @test.namespace("foo").should == "http://bar.baz/asdf"
220
+ @test.namespace("bar").should == "http://bar.asdf.baz/asdf"
221
+
222
+ lambda { @test.delete_all_namespaces! }.should_not raise_error
223
+
224
+ @test.namespace("foo").should == nil
225
+ @test.namespace("bar").should == nil
226
+ end
227
+
228
+
229
+ TEST_DATA = <<END
230
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
231
+ @prefix contact: <http://www.w3.org/2000/10/swap/pim/contact#>.
232
+
233
+ <http://www.example.com/test/foo/#{ Time.now.to_i }>
234
+ rdf:type contact:Person;
235
+ contact:fullName "Foo Bar";
236
+ contact:mailbox <mailto:foo@bar.org>;
237
+ contact:personalTitle "Mr.".
238
+ END
239
+
240
+ it "should be able to add data to the test repository" do
241
+ result = nil
242
+ original_count = @test.size
243
+ lambda { result = @test.add!(TEST_DATA) }.should_not raise_error
244
+ @test.size.should == original_count + 4 # number of statements in TEST_DATA
245
+ end
246
+
247
+ it "should refuse to delete all statements if 'safety' is not specified" do
248
+ result = nil
249
+ lambda { @test.delete_statements! }.should raise_error
250
+ end
251
+
252
+ it "should delete all statements if 'safety' is false" do
253
+ lambda { @test.add!(TEST_DATA) }.should_not raise_error
254
+ @test.size.should > 0
255
+
256
+ lambda { @test.delete_statements!({}, false) }.should_not raise_error
257
+ @test.size.should == 0
258
+ end
259
+
260
+ it "should be able to delete all data from the test repository" do
261
+ lambda { @test.add!(TEST_DATA) }.should_not raise_error
262
+ @test.size.should > 0
263
+
264
+ lambda { @test.delete_all_statements! }.should_not raise_error
265
+ @test.size.should == 0
266
+ end
267
+
268
+ it "should be able to count the entries in the test repository" do
269
+ result = nil
270
+ lambda { result = @test.size }.should_not raise_error
271
+ end
272
+
273
+ end