ruby-sesame 0.1.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.
@@ -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