From 26e0e1ab72f7a18d7e2d7d3ffe71ad5427a9cf82 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Thu, 20 Dec 2018 17:54:24 -0800 Subject: [PATCH 1/8] Update travis config to deal with rubygems not supporting ruby < 2.3 any longer. See https://github.com/rubygems/rubygems/issues/2534. --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ed78221..d52b2ac1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: ruby bundler_args: --without debug script: "bundle exec rspec spec" -before_install: "gem update --system" - +before_install: + - 'gem update --system --conservative || (gem i "rubygems-update:~>2.7" --no-document && update_rubygems)' + - 'gem update bundler --conservative' env: - CI=true gemfile: From 0508243c20c9ebe4515ad2d1d6206d8591b95781 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 24 Dec 2018 15:43:26 -0800 Subject: [PATCH 2/8] Add 2.6 to travis RVM matrix. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d52b2ac1..0c30004f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ rvm: - 2.3 - 2.4 - 2.5 + - 2.6 - jruby-9 - rbx-3 cache: bundler From 0627034856d8d0831a73a8781d4cb266229399dc Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 1 Jan 2019 12:24:48 -0800 Subject: [PATCH 3/8] Update Gemfile. --- Gemfile-pure | 1 - sparql-client.gemspec | 5 ----- 2 files changed, 6 deletions(-) diff --git a/Gemfile-pure b/Gemfile-pure index cb83032f..1ab8f736 100644 --- a/Gemfile-pure +++ b/Gemfile-pure @@ -22,6 +22,5 @@ end group :debug do gem 'shotgun' - gem "wirble" gem "byebug", platforms: :mri end diff --git a/sparql-client.gemspec b/sparql-client.gemspec index 5e7b657c..858eb464 100755 --- a/sparql-client.gemspec +++ b/sparql-client.gemspec @@ -33,10 +33,5 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'webmock', '~> 3.1' gem.add_development_dependency 'yard' , '~> 0.9.12' - # Rubinius has it's own dependencies - if RUBY_ENGINE == "rbx" && RUBY_VERSION >= "2.1.0" - gem.add_runtime_dependency "json" - end - gem.post_install_message = nil end From 1546bd738b0ec4278d4f6d812abca814bdf2dc3a Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 1 Jul 2019 15:27:58 -0700 Subject: [PATCH 4/8] Add default for User-Agent HTTP header, and fix code that sets default headers when creating the client. Fixes #94. --- README.md | 9 +++++++++ lib/sparql/client.rb | 15 +++++++++++++-- spec/client_spec.rb | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ccd63211..c3487aba 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,15 @@ This is a [Ruby][] implementation of a [SPARQL][] client for [RDF.rb][]. require 'sparql/client' sparql = SPARQL::Client.new("http://dbpedia.org/sparql") ``` + +### Querying a remote SPARQL endpoint with a custom User-Agent +By default, SPARQL::Client adds a `User-Agent` field to requests, but applications may choose to provide their own, using the `headers` option: + +```ruby +require 'sparql/client' +sparql = SPARQL::Client.new("http://dbpedia.org/sparql", headers: {'User-Agent' => 'MyBotName'}) +``` + ### Querying a remote SPARQL endpoint with a specified default graph ```ruby diff --git a/lib/sparql/client.rb b/lib/sparql/client.rb index de8ffdc5..ceb6ac90 100644 --- a/lib/sparql/client.rb +++ b/lib/sparql/client.rb @@ -86,6 +86,11 @@ class ServerError < StandardError; end # @option options [Symbol] :method (DEFAULT_METHOD) # @option options [Number] :protocol (DEFAULT_PROTOCOL) # @option options [Hash] :headers + # HTTP Request headers + # + # Defaults `Accept` header based on available reader content types if triples are expected and to SPARQL result types otherwise, to allow for content negotiation based on available readers. + # + # Defaults `User-Agent` header, unless one is specified. # @option options [Hash] :read_timeout def initialize(url, options = {}, &block) case url @@ -339,7 +344,7 @@ def update(query, options = {}) # @option options [Hash] :headers # @return [String] def response(query, options = {}) - headers = options[:headers] || {} + headers = options[:headers] || @headers headers['Accept'] = options[:content_type] if options[:content_type] request(query, headers) do |response| case response @@ -615,7 +620,7 @@ def self.serialize_patterns(patterns, use_vars = false) RDF::Statement.from(pattern).to_triple.each_with_index.map do |v, i| if i == 1 SPARQL::Client.serialize_predicate(v) - else + else SPARQL::Client.serialize_value(v, use_vars) end end @@ -673,6 +678,11 @@ def http_klass(scheme) # # @param [String, #to_s] query # @param [Hash{String => String}] headers + # HTTP Request headers + # + # Defaults `Accept` header based on available reader content types if triples are expected and to SPARQL result types otherwise, to allow for content negotiation based on available readers. + # + # Defaults `User-Agent` header, unless one is specified. # @yield [response] # @yieldparam [Net::HTTPResponse] response # @return [Net::HTTPResponse] @@ -686,6 +696,7 @@ def request(query, headers = {}, &block) else RESULT_ALL end + headers['User-Agent'] ||= "Ruby SPARQL::Client/#{SPARQL::Client::VERSION}" request = send("make_#{request_method(query)}_request", query, headers) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 90368232..07c9d4bd 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -167,7 +167,7 @@ def response(header) end context "Accept Header" do - it "should use application/sparql-results+json for ASK" do + it "includes application/sparql-results+json for ASK" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) subject.query(ask_query) @@ -175,7 +175,7 @@ def response(header) with(:headers => {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) end - it "should use application/n-triples for CONSTRUCT" do + it "includes application/n-triples for CONSTRUCT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) subject.query(construct_query) @@ -183,7 +183,7 @@ def response(header) with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end - it "should use application/n-triples for DESCRIBE" do + it "includes application/n-triples for DESCRIBE" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) subject.query(describe_query) @@ -191,7 +191,7 @@ def response(header) with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end - it "should use application/sparql-results+json for SELECT" do + it "includes application/sparql-results+json for SELECT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) subject.query(select_query) @@ -200,6 +200,33 @@ def response(header) end end + context 'User-Agent header' do + it "uses default if not specified" do + WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). + to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + subject.query(select_query) + expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). + with(:headers => {'User-Agent' => "Ruby SPARQL::Client/#{SPARQL::Client::VERSION}"}) + end + + it "uses user-provided value in query" do + WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). + to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + subject.query(select_query, headers: {'User-Agent' => 'Foo'}) + expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). + with(:headers => {'User-Agent' => "Foo"}) + end + + it "uses user-provided value in initialization" do + client = SPARQL::Client.new('http://data.linkedmdb.org/sparql', headers: {'User-Agent' => 'Foo'}) + WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). + to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + client.query(select_query) + expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). + with(:headers => {'User-Agent' => "Foo"}) + end + end + context "Alternative Endpoint" do it "should use the default endpoint if no alternative endpoint is provided" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). From 543e2cdfa65d06f85a743c19e13ea19339dfac0e Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 13 Oct 2018 12:29:49 -0700 Subject: [PATCH 5/8] Add `Client#close` to shutdown any HTTP connection and object finalizer to do the same. Fixes #86. --- README.md | 4 +- lib/sparql/client.rb | 24 ++++++++--- sparql-client.gemspec | 2 +- spec/client_spec.rb | 63 ++++++++++++++++------------- spec/query_spec.rb | 90 ++++++++++++++++++++--------------------- spec/repository_spec.rb | 2 +- spec/update_spec.rb | 62 ++++++++++++++-------------- 7 files changed, 133 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index c3487aba..8554ae1a 100644 --- a/README.md +++ b/README.md @@ -125,9 +125,9 @@ sparql.delete_data(data) * [Ruby](http://ruby-lang.org/) (>= 2.2.2) * [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.0) -* [Net::HTTP::Persistent](http://rubygems.org/gems/net-http-persistent) (>= 1.4) +* [Net::HTTP::Persistent](http://rubygems.org/gems/net-http-persistent) (~> 3.0) * Soft dependency on [SPARQL](http://rubygems.org/gems/sparql) (~> 3.0) -* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.7) +* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.8) ## Installation diff --git a/lib/sparql/client.rb b/lib/sparql/client.rb index ceb6ac90..3ea1830c 100644 --- a/lib/sparql/client.rb +++ b/lib/sparql/client.rb @@ -100,6 +100,9 @@ def initialize(url, options = {}, &block) @url, @options = RDF::URI.new(url.to_s), options.dup @headers = @options.delete(:headers) || {} @http = http_klass(@url.scheme) + + # Close the http connection when object is deallocated + ObjectSpace.define_finalizer(self, proc {@http.shutdown if @http.respond_to?(:shutdown)}) end if block_given? @@ -110,6 +113,16 @@ def initialize(url, options = {}, &block) end end + ## + # Closes a client instance by finishing the connection. + # The client is unavailable for any further data operations; an IOError is raised if such an attempt is made. I/O streams are automatically closed when they are claimed by the garbage collector. + # @return [void] `self` + def close + @http.shutdown if @http + @http = nil + self + end + ## # Executes a boolean `ASK` query. # @@ -293,6 +306,7 @@ def nodes # @option options [String] :content_type # @option options [Hash] :headers # @return [Array] + # @raise [IOError] if connection is closed # @see http://www.w3.org/TR/sparql11-protocol/#query-operation def query(query, options = {}) @op = :query @@ -320,6 +334,7 @@ def query(query, options = {}) # @option options [String] :content_type # @option options [Hash] :headers # @return [void] `self` + # @raise [IOError] if connection is closed # @see http://www.w3.org/TR/sparql11-protocol/#update-operation def update(query, options = {}) @op = :update @@ -343,6 +358,7 @@ def update(query, options = {}) # @option options [String] :content_type # @option options [Hash] :headers # @return [String] + # @raise [IOError] if connection is closed def response(query, options = {}) headers = options[:headers] || @headers headers['Accept'] = options[:content_type] if options[:content_type] @@ -663,11 +679,7 @@ def http_klass(scheme) value = ENV['https_proxy'] proxy_url = URI.parse(value) unless value.nil? || value.empty? end - klass = if Net::HTTP::Persistent::VERSION >= '3.0' - Net::HTTP::Persistent.new(name: self.class.to_s, proxy: proxy_url) - else - Net::HTTP::Persistent.new(self.class.to_s, proxy_url) - end + klass = Net::HTTP::Persistent.new(name: self.class.to_s, proxy: proxy_url) klass.keep_alive = @options[:keep_alive] || 120 klass.read_timeout = @options[:read_timeout] || 60 klass @@ -686,6 +698,7 @@ def http_klass(scheme) # @yield [response] # @yieldparam [Net::HTTPResponse] response # @return [Net::HTTPResponse] + # @raise [IOError] if connection is closed # @see http://www.w3.org/TR/sparql11-protocol/#query-operation def request(query, headers = {}, &block) # Make sure an appropriate Accept header is present @@ -704,6 +717,7 @@ def request(query, headers = {}, &block) pre_http_hook(request) if respond_to?(:pre_http_hook) + raise IOError, "Client has been closed" unless @http response = @http.request(::URI.parse(url.to_s), request) post_http_hook(response) if respond_to?(:post_http_hook) diff --git a/sparql-client.gemspec b/sparql-client.gemspec index 858eb464..458c8bd4 100755 --- a/sparql-client.gemspec +++ b/sparql-client.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |gem| gem.required_ruby_version = '>= 2.2.2' gem.requirements = [] gem.add_runtime_dependency 'rdf', '~> 3.0' - gem.add_runtime_dependency 'net-http-persistent', '>= 2.9', '< 4' + gem.add_runtime_dependency 'net-http-persistent', '~> 3.0' gem.add_development_dependency 'rdf-spec', '~> 3.0' gem.add_development_dependency 'sparql', '~> 3.0' gem.add_development_dependency 'rspec', '~> 3.7' diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 07c9d4bd..8bc5b0d8 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -55,65 +55,65 @@ def response(header) end end - it "should handle successful response with plain header" do + it "handles successful response with plain header" do expect(subject).to receive(:request).and_yield response('text/plain') expect(RDF::Reader).to receive(:for).with(:content_type => 'text/plain').and_call_original subject.query(query) end - it "should handle successful response with boolean header" do + it "handles successful response with boolean header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_BOOL) expect(subject.query(query)).to be_falsey end - it "should handle successful response with JSON header" do + it "handles successful response with JSON header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_JSON) expect(subject.class).to receive(:parse_json_bindings) subject.query(query) end - it "should handle successful response with XML header" do + it "handles successful response with XML header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_XML) expect(subject.class).to receive(:parse_xml_bindings) subject.query(query) end - it "should handle successful response with CSV header" do + it "handles successful response with CSV header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_CSV) expect(subject.class).to receive(:parse_csv_bindings) subject.query(query) end - it "should handle successful response with TSV header" do + it "handles successful response with TSV header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_TSV) expect(subject.class).to receive(:parse_tsv_bindings) subject.query(query) end - it "should handle successful response with overridden XML header" do + it "handles successful response with overridden XML header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_XML) expect(subject.class).to receive(:parse_json_bindings) subject.query(query, :content_type => SPARQL::Client::RESULT_JSON) end - it "should handle successful response with no content type" do + it "handles successful response with no content type" do expect(subject).to receive(:request).and_yield response(nil) expect { subject.query(query) }.not_to raise_error end - it "should handle successful response with overridden plain header" do + it "handles successful response with overridden plain header" do expect(subject).to receive(:request).and_yield response('text/plain') expect(RDF::Reader).to receive(:for).with(:content_type => 'text/turtle').and_call_original subject.query(query, :content_type => 'text/turtle') end - it "should handle successful response with custom headers" do + it "handles successful response with custom headers" do expect(subject).to receive(:request).with(anything, "Authorization" => "Basic XXX=="). and_yield response('text/plain') subject.query(query, :headers => {"Authorization" => "Basic XXX=="}) end - it "should handle successful response with initial custom headers" do + it "handles successful response with initial custom headers" do options = {:headers => {"Authorization" => "Basic XXX=="}, :method => :get} client = SPARQL::Client.new('http://data.linkedmdb.org/sparql', options) client.instance_variable_set :@http, double(:request => response('text/plain')) @@ -121,7 +121,7 @@ def response(header) client.query(query) end - it "should enable overriding the http method" do + it "enables overriding the http method" do stub_request(:get, "http://data.linkedmdb.org/sparql?query=DESCRIBE%20?kb%20WHERE%20%7B%20?kb%20%3Chttp://data.linkedmdb.org/resource/movie/actor_name%3E%20%22Kevin%20Bacon%22%20.%20%7D"). to_return(:status => 200, :body => "", :headers => { 'Content-Type' => 'application/n-triples'}) allow(subject).to receive(:request_method).with(query).and_return(:get) @@ -129,7 +129,7 @@ def response(header) subject.query(query) end - it "should support international characters in response body" do + it "supports international characters in response body" do client = SPARQL::Client.new('http://dbpedia.org/sparql') json = { :results => { @@ -145,6 +145,11 @@ def response(header) expect(result[:name].to_s).to eq "東京" end + it "generates IOError when querying closed client" do + subject.close + expect{ subject.query(ask_query) }.to raise_error IOError + end + context "Redirects" do before do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). @@ -167,7 +172,7 @@ def response(header) end context "Accept Header" do - it "includes application/sparql-results+json for ASK" do + it "uses application/sparql-results+json for ASK" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) subject.query(ask_query) @@ -175,7 +180,7 @@ def response(header) with(:headers => {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) end - it "includes application/n-triples for CONSTRUCT" do + it "uses application/n-triples for CONSTRUCT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) subject.query(construct_query) @@ -183,7 +188,7 @@ def response(header) with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end - it "includes application/n-triples for DESCRIBE" do + it "uses application/n-triples for DESCRIBE" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) subject.query(describe_query) @@ -191,7 +196,7 @@ def response(header) with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end - it "includes application/sparql-results+json for SELECT" do + it "uses application/sparql-results+json for SELECT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) subject.query(select_query) @@ -228,21 +233,21 @@ def response(header) end context "Alternative Endpoint" do - it "should use the default endpoint if no alternative endpoint is provided" do + it "uses the default endpoint if no alternative endpoint is provided" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200) subject.update(update_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql") end - it "should use the alternative endpoint if provided" do + it "uses the alternative endpoint if provided" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/alternative'). to_return(:body => '', :status => 200) subject.update(update_query, { endpoint: "http://data.linkedmdb.org/alternative" }) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/alternative") end - it "should not use the alternative endpoint for a select query" do + it "does not use the alternative endpoint for a select query" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). to_return(:body => '', :status => 200) WebMock.stub_request(:any, 'http://data.linkedmdb.org/alternative'). @@ -325,7 +330,7 @@ def response(header) let(:graph) {RDF::Graph.new << RDF::Statement(RDF::URI('http://example/s'), RDF::URI('http://example/p'), "o")} subject {SPARQL::Client.new(repo)} - it "should query repository" do + it "queries repository" do expect(SPARQL).to receive(:execute).with(query, repo, {}) subject.query(query) end @@ -373,7 +378,7 @@ def response(header) end context "when parsing XML" do - it "should parse binding results correctly" do + it "parses binding results correctly" do xml = File.read("spec/fixtures/results.xml") nodes = {} solutions = SPARQL::Client::parse_xml_bindings(xml, nodes) @@ -389,19 +394,19 @@ def response(header) expect(solutions[0]["x"]).to eq nodes["r2"] end - it "should parse boolean true results correctly" do + it "parses boolean true results correctly" do xml = File.read("spec/fixtures/bool_true.xml") expect(SPARQL::Client::parse_xml_bindings(xml)).to eq true end - it "should parse boolean false results correctly" do + it "parses boolean false results correctly" do xml = File.read("spec/fixtures/bool_false.xml") expect(SPARQL::Client::parse_xml_bindings(xml)).to eq false end end context "when parsing JSON" do - it "should parse binding results correctly" do + it "parses binding results correctly" do xml = File.read("spec/fixtures/results.json") nodes = {} solutions = SPARQL::Client::parse_json_bindings(xml, nodes) @@ -417,19 +422,19 @@ def response(header) expect(solutions[0]["x"]).to eq nodes["r2"] end - it "should parse boolean true results correctly" do + it "parses boolean true results correctly" do json = '{"boolean": true}' expect(SPARQL::Client::parse_json_bindings(json)).to eq true end - it "should parse boolean true results correctly" do + it "parses boolean true results correctly" do json = '{"boolean": false}' expect(SPARQL::Client::parse_json_bindings(json)).to eq false end end context "when parsing CSV" do - it "should parse binding results correctly" do + it "parses binding results correctly" do csv = File.read("spec/fixtures/results.csv") nodes = {} solutions = SPARQL::Client::parse_csv_bindings(csv, nodes) @@ -445,7 +450,7 @@ def response(header) end context "when parsing TSV" do - it "should parse binding results correctly" do + it "parses binding results correctly" do tsv = File.read("spec/fixtures/results.tsv") nodes = {} solutions = SPARQL::Client::parse_tsv_bindings(tsv, nodes) diff --git a/spec/query_spec.rb b/spec/query_spec.rb index 98ad7645..bcac1fa9 100644 --- a/spec/query_spec.rb +++ b/spec/query_spec.rb @@ -4,19 +4,19 @@ subject {SPARQL::Client::Query} context "when building queries" do - it "should support ASK queries" do + it "supports ASK queries" do expect(subject).to respond_to(:ask) end - it "should support SELECT queries" do + it "supports SELECT queries" do expect(subject).to respond_to(:select) end - it "should support DESCRIBE queries" do + it "supports DESCRIBE queries" do expect(subject).to respond_to(:describe) end - it "should support CONSTRUCT queries" do + it "supports CONSTRUCT queries" do expect(subject).to respond_to(:construct) end end @@ -84,38 +84,38 @@ end context "when building SELECT queries" do - it "should support basic graph patterns" do + it "supports basic graph patterns" do expect(subject.select.where([:s, :p, :o]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . }" end - it "should support projection" do + it "supports projection" do expect(subject.select(:s).where([:s, :p, :o]).to_s).to eq "SELECT ?s WHERE { ?s ?p ?o . }" expect(subject.select(:s, :p).where([:s, :p, :o]).to_s).to eq "SELECT ?s ?p WHERE { ?s ?p ?o . }" expect(subject.select(:s, :p, :o).where([:s, :p, :o]).to_s).to eq "SELECT ?s ?p ?o WHERE { ?s ?p ?o . }" end - it "should support FROM" do + it "supports FROM" do uri = "http://example.org/dft.ttl" expect(subject.select.from(RDF::URI.new(uri)).where([:s, :p, :o]).to_s).to eq "SELECT * FROM <#{uri}> WHERE { ?s ?p ?o . }" end - it "should support DISTINCT" do + it "supports DISTINCT" do expect(subject.select(:s, :distinct => true).where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT ?s WHERE { ?s ?p ?o . }" expect(subject.select(:s).distinct.where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT ?s WHERE { ?s ?p ?o . }" expect(subject.select.distinct.where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT * WHERE { ?s ?p ?o . }" end - it "should support REDUCED" do + it "supports REDUCED" do expect(subject.select(:s, :reduced => true).where([:s, :p, :o]).to_s).to eq "SELECT REDUCED ?s WHERE { ?s ?p ?o . }" expect(subject.select(:s).reduced.where([:s, :p, :o]).to_s).to eq "SELECT REDUCED ?s WHERE { ?s ?p ?o . }" end - it "should support GRAPH" do + it "supports GRAPH" do expect(subject.select.graph(:g).where([:s, :p, :o]).to_s).to eq "SELECT * WHERE { GRAPH ?g { ?s ?p ?o . } }" expect(subject.select.graph('http://example.org/').where([:s, :p, :o]).to_s).to eq "SELECT * WHERE { GRAPH { ?s ?p ?o . } }" end - it "should support COUNT" do + it "supports COUNT" do expect(subject.select(:count => { :s => :c }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" expect(subject.select(:count => { :s => :c }, :distinct => true).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(DISTINCT ?s) AS ?c ) WHERE { ?s ?p ?o . }" expect(subject.select(:count => { :s => '?c' }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" @@ -123,7 +123,7 @@ expect(subject.select(:o, :count => { :s => :c }).where([:s, :p, :o]).to_s).to eq "SELECT ?o ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" end - it "should support VALUES" do + it "supports VALUES" do expect(subject.select(:s).where([:s, :p, :o]).values(:o, "Object").to_s).to eq 'SELECT ?s WHERE { ?s ?p ?o . VALUES (?o) { ( "Object" ) } }' expect(subject.select(:s).where([:s, :p, :o]).values(:o, "1", "2").to_s).to eq 'SELECT ?s WHERE { ?s ?p ?o . VALUES (?o) { ( "1" ) ( "2" ) } }' expect(subject.select(:s).where([:s, :p, :o]).values([:o, :p], ["Object", "Predicate"]).to_s).to eq 'SELECT ?s WHERE { ?s ?p ?o . VALUES (?o ?p) { ( "Object" "Predicate" ) } }' @@ -131,12 +131,12 @@ expect(subject.select(:s).where([:s, :p, :o]).values([:o, :p], [nil, "2"], ["3", nil]).to_s).to eq 'SELECT ?s WHERE { ?s ?p ?o . VALUES (?o ?p) { ( UNDEF "2" ) ( "3" UNDEF ) } }' end - it "should support GROUP BY" do + it "supports GROUP BY" do expect(subject.select(:s).where([:s, :p, :o]).group_by(:s).to_s).to eq "SELECT ?s WHERE { ?s ?p ?o . } GROUP BY ?s" expect(subject.select(:s).where([:s, :p, :o]).group_by('?s').to_s).to eq "SELECT ?s WHERE { ?s ?p ?o . } GROUP BY ?s" end - it "should support ORDER BY" do + it "supports ORDER BY" do expect(subject.select.where([:s, :p, :o]).order_by(:o).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o" expect(subject.select.where([:s, :p, :o]).order_by(:o, :p).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o ?p" expect(subject.select.where([:s, :p, :o]).order_by('?o').to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o" @@ -157,70 +157,70 @@ expect { subject.select.where([:s, :p, :o]).order_by(42 => :asc).to_s }.to raise_error(ArgumentError) end - it "should support ORDER BY ASC" do + it "supports ORDER BY ASC" do expect(subject.select.where([:s, :p, :o]).order.asc(:o).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" expect(subject.select.where([:s, :p, :o]).asc(:o).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" expect { subject.select.where([:s, :p, :o]).order.asc(:o, :p).to_s }.to raise_error(ArgumentError) end - it "should support ORDER BY DESC" do + it "supports ORDER BY DESC" do expect(subject.select.where([:s, :p, :o]).order.desc(:o).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" expect(subject.select.where([:s, :p, :o]).desc(:o).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" expect { subject.select.where([:s, :p, :o]).order.desc(:o, :p).to_s }.to raise_error(ArgumentError) end - it "should support OFFSET" do + it "supports OFFSET" do expect(subject.select.where([:s, :p, :o]).offset(100).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } OFFSET 100" end - it "should support LIMIT" do + it "supports LIMIT" do expect(subject.select.where([:s, :p, :o]).limit(10).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } LIMIT 10" end - it "should support OFFSET with LIMIT" do + it "supports OFFSET with LIMIT" do expect(subject.select.where([:s, :p, :o]).offset(100).limit(10).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } OFFSET 100 LIMIT 10" expect(subject.select.where([:s, :p, :o]).slice(100, 10).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } OFFSET 100 LIMIT 10" end - it "should support string PREFIX" do + it "supports string PREFIX" do prefixes = ["dc: ", "foaf: "] expect(subject.select.prefix(prefixes[0]).prefix(prefixes[1]).where([:s, :p, :o]).to_s).to eq "PREFIX dc: PREFIX foaf: SELECT * WHERE { ?s ?p ?o . }" end - it "should support hash PREFIX" do + it "supports hash PREFIX" do prefixes = [{dc: RDF::URI("http://purl.org/dc/elements/1.1/")}, {foaf: RDF::URI("http://xmlns.com/foaf/0.1/")}] expect(subject.select.prefix(prefixes[0]).prefix(prefixes[1]).where([:s, :p, :o]).to_s).to eq "PREFIX dc: PREFIX foaf: SELECT * WHERE { ?s ?p ?o . }" end - it "should support multiple values in PREFIX hash" do + it "supports multiple values in PREFIX hash" do expect(subject.select.prefix(dc: RDF::URI("http://purl.org/dc/elements/1.1/"), foaf: RDF::URI("http://xmlns.com/foaf/0.1/")).where([:s, :p, :o]).to_s).to eq "PREFIX dc: PREFIX foaf: SELECT * WHERE { ?s ?p ?o . }" end - it "should raise an ArgumentError for invalid PREFIX type" do + it "raises an ArgumentError for invalid PREFIX type" do inavlid_prefix_types = [RDF::URI('missing prefix hash'), 0, []] inavlid_prefix_types.each do |invalid_arg| expect { subject.select.prefix(invalid_arg) }.to raise_error ArgumentError, "prefix must be a kind of String or a Hash" end end - it "should support OPTIONAL" do + it "supports OPTIONAL" do expect(subject.select.where([:s, :p, :o]).optional([:s, RDF.type, :o], [:s, RDF::URI("http://purl.org/dc/terms/abstract"), :o]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . OPTIONAL { ?s a ?o . ?s ?o . } }" end - it "should support OPTIONAL with filter in block" do + it "supports OPTIONAL with filter in block" do expect(subject.select.where([:s, :p, :o]).optional([:s, RDF.value, :o]) {filter("langmatches(lang(?o), 'en')")}.to_s).to eq "SELECT * WHERE { ?s ?p ?o . OPTIONAL { ?s ?o . FILTER(langmatches(lang(?o), 'en')) . } }" end - it "should support multiple OPTIONALs" do + it "supports multiple OPTIONALs" do expect(subject.select.where([:s, :p, :o]).optional([:s, RDF.type, :o]).optional([:s, RDF::URI("http://purl.org/dc/terms/abstract"), :o]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . OPTIONAL { ?s a ?o . } OPTIONAL { ?s ?o . } }" end - it "should support subqueries" do + it "supports subqueries" do subquery = subject.select.where([:s, :p, :o]) expect(subject.select.where(subquery).where([:s, :p, :o]).to_s).to eq "SELECT * WHERE { { SELECT * WHERE { ?s ?p ?o . } } . ?s ?p ?o . }" end - it "should support subqueries using block" do + it "supports subqueries using block" do expect(subject.select.where([:s, :p, :o]) {select.where([:s, :p, :o])}.to_s).to eq "SELECT * WHERE { { SELECT * WHERE { ?s ?p ?o . } } . ?s ?p ?o . }" end @@ -229,40 +229,40 @@ end context "with property paths" do - it "should support the InversePath expression" do + it "supports the InversePath expression" do expect(subject.select.where([:s, ["^",RDF::RDFS.subClassOf], :o]).to_s).to eq "SELECT * WHERE { ?s ^<#{RDF::RDFS.subClassOf}> ?o . }" end - it "should support the SequencePath expression" do + it "supports the SequencePath expression" do expect(subject.select.where([:s, [RDF.type,"/",RDF::RDFS.subClassOf], :o]).to_s).to eq "SELECT * WHERE { ?s a/<#{RDF::RDFS.subClassOf}> ?o . }" end - it "should support the AlternativePath expression" do + it "supports the AlternativePath expression" do expect(subject.select.where([:s, [RDF.type,"|",RDF::RDFS.subClassOf], :o]).to_s).to eq "SELECT * WHERE { ?s a|<#{RDF::RDFS.subClassOf}> ?o . }" end - it "should support the ZeroOrMore expression" do + it "supports the ZeroOrMore expression" do expect(subject.select.where([:s, [RDF::RDFS.subClassOf,"*"], :o]).to_s).to eq "SELECT * WHERE { ?s <#{RDF::RDFS.subClassOf}>* ?o . }" end - it "should support the OneOrMore expression" do + it "supports the OneOrMore expression" do expect(subject.select.where([:s, [RDF::RDFS.subClassOf,"+"], :o]).to_s).to eq "SELECT * WHERE { ?s <#{RDF::RDFS.subClassOf}>+ ?o . }" end - it "should support the ZeroOrOne expression" do + it "supports the ZeroOrOne expression" do expect(subject.select.where([:s, [RDF::RDFS.subClassOf,"?"], :o]).to_s).to eq "SELECT * WHERE { ?s <#{RDF::RDFS.subClassOf}>? ?o . }" end - it "should support the NegatedPropertySet expression" do + it "supports the NegatedPropertySet expression" do expect(subject.select.where([:s, ["!",[RDF::RDFS.subClassOf,"|",RDF.type]], :o]).to_s).to eq "SELECT * WHERE { ?s !(<#{RDF::RDFS.subClassOf}>|a) ?o . }" end end context "with unions" do - it "should support pattern arguments" do + it "supports pattern arguments" do expect(subject.select.where([:s, :p, :o]).union([:s, :p, :o]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } UNION { ?s ?p ?o . }" end - it "should support query arguments" do + it "supports query arguments" do subquery = subject.select.where([:s, :p, :o]) expect(subject.select.where([:s, :p, :o]).union(subquery).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } UNION { ?s ?p ?o . }" end - it "should support block" do + it "supports block" do expect(subject.select.where([:s, :p, :o]).union {|q| q.where([:s, :p, :o])}.to_s).to eq "SELECT * WHERE { ?s ?p ?o . } UNION { ?s ?p ?o . }" end @@ -277,16 +277,16 @@ end context "with minus" do - it "should support pattern arguments" do + it "supports pattern arguments" do expect(subject.select.where([:s, :p, :o]).minus([:s, :p, :o]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . MINUS { ?s ?p ?o . } }" end - it "should support query arguments" do + it "supports query arguments" do subquery = subject.select.where([:s, :p, :o]) expect(subject.select.where([:s, :p, :o]).minus(subquery).to_s).to eq "SELECT * WHERE { ?s ?p ?o . MINUS { ?s ?p ?o . } }" end - it "should support block" do + it "supports block" do expect(subject.select.where([:s, :p, :o]).minus {|q| q.where([:s, :p, :o])}.to_s).to eq "SELECT * WHERE { ?s ?p ?o . MINUS { ?s ?p ?o . } }" end @@ -302,17 +302,17 @@ end context "when building DESCRIBE queries" do - it "should support basic graph patterns" do + it "supports basic graph patterns" do expect(subject.describe.where([:s, :p, :o]).to_s).to eq "DESCRIBE * WHERE { ?s ?p ?o . }" end - it "should support projection" do + it "supports projection" do expect(subject.describe(:s).where([:s, :p, :o]).to_s).to eq "DESCRIBE ?s WHERE { ?s ?p ?o . }" expect(subject.describe(:s, :p).where([:s, :p, :o]).to_s).to eq "DESCRIBE ?s ?p WHERE { ?s ?p ?o . }" expect(subject.describe(:s, :p, :o).where([:s, :p, :o]).to_s).to eq "DESCRIBE ?s ?p ?o WHERE { ?s ?p ?o . }" end - it "should support RDF::URI arguments" do + it "supports RDF::URI arguments" do uris = ['http://www.bbc.co.uk/programmes/b007stmh#programme', 'http://www.bbc.co.uk/programmes/b00lg2xb#programme'] expect(subject.describe(RDF::URI.new(uris[0]),RDF::URI.new(uris[1])).to_s).to eq "DESCRIBE <#{uris[0]}> <#{uris[1]}>" end @@ -323,7 +323,7 @@ end context "when building CONSTRUCT queries" do - it "should support basic graph patterns" do + it "supports basic graph patterns" do expect(subject.construct([:s, :p, :o]).where([:s, :p, :o]).to_s).to eq "CONSTRUCT { ?s ?p ?o . } WHERE { ?s ?p ?o . }" end diff --git a/spec/repository_spec.rb b/spec/repository_spec.rb index 5c706572..ff42ad26 100644 --- a/spec/repository_spec.rb +++ b/spec/repository_spec.rb @@ -20,6 +20,6 @@ @base_repo.insert(*@statements) end - its(:count) {should == @statements.size} + its(:count) {is_expected.to eql @statements.size} end end diff --git a/spec/update_spec.rb b/spec/update_spec.rb index 44f9e2ce..b1df03b4 100644 --- a/spec/update_spec.rb +++ b/spec/update_spec.rb @@ -4,51 +4,51 @@ subject {SPARQL::Client::Update} context "when building queries" do - it "should support INSERT DATA operations" do + it "supports INSERT DATA operations" do expect(subject).to respond_to(:insert_data) end - it "should support DELETE DATA operations" do + it "supports DELETE DATA operations" do expect(subject).to respond_to(:delete_data) end - it "should support DELETE/INSERT operations", pending: true do + it "supports DELETE/INSERT operations", pending: true do expect(subject).to respond_to(:what) expect(subject).to respond_to(:delete) expect(subject).to respond_to(:insert) end - it "should support LOAD operations" do + it "supports LOAD operations" do expect(subject).to respond_to(:load) end - it "should support CLEAR operations" do + it "supports CLEAR operations" do expect(subject).to respond_to(:clear) end - it "should support CREATE operations" do + it "supports CREATE operations" do expect(subject).to respond_to(:create) end - it "should support DROP operations" do + it "supports DROP operations" do expect(subject).to respond_to(:drop) end - it "should support COPY operations", pending: true do + it "supports COPY operations", pending: true do expect(subject).to respond_to(:copy) # TODO end - it "should support MOVE operations", pending: true do + it "supports MOVE operations", pending: true do expect(subject).to respond_to(:move) # TODO end - it "should support ADD operations", pending: true do + it "supports ADD operations", pending: true do expect(subject).to respond_to(:add) # TODO end end context "when building INSERT DATA queries" do - it "should support empty input" do + it "supports empty input" do expect(subject.insert_data(RDF::Graph.new).to_s).to eq "INSERT DATA {\n}\n" end @@ -56,14 +56,14 @@ expect(subject.insert_data(RDF::Graph.new)).not_to be_expects_statements end - it "should support non-empty input" do + it "supports non-empty input" do data = RDF::Graph.new do |graph| graph << [RDF::URI('http://example.org/jhacker'), RDF::URI("http://xmlns.com/foaf/0.1/name"), "J. Random Hacker"] end expect(subject.insert_data(data).to_s).to eq "INSERT DATA {\n \"J. Random Hacker\" .\n}\n" end - it "should support the GRAPH modifier" do + it "supports the GRAPH modifier" do [subject.insert_data(RDF::Graph.new, :graph => 'http://example.org/'), subject.insert_data(RDF::Graph.new).graph('http://example.org/')].each do |example| expect(example.to_s).to eq "INSERT DATA { GRAPH {\n}}\n" @@ -72,7 +72,7 @@ end context "when building DELETE DATA queries" do - it "should support empty input" do + it "supports empty input" do expect(subject.delete_data(RDF::Graph.new).to_s).to eq "DELETE DATA {\n}\n" end @@ -80,14 +80,14 @@ expect(subject.delete_data(RDF::Graph.new)).to be_expects_statements end - it "should support non-empty input" do + it "supports non-empty input" do data = RDF::Graph.new do |graph| graph << [RDF::URI('http://example.org/jhacker'), RDF::URI("http://xmlns.com/foaf/0.1/name"), "J. Random Hacker"] end expect(subject.delete_data(data).to_s).to eq "DELETE DATA {\n \"J. Random Hacker\" .\n}\n" end - it "should support the GRAPH modifier" do + it "supports the GRAPH modifier" do [subject.delete_data(RDF::Graph.new, :graph => 'http://example.org/'), subject.delete_data(RDF::Graph.new).graph('http://example.org/')].each do |example| expect(example.to_s).to eq "DELETE DATA { GRAPH {\n}}\n" @@ -102,7 +102,7 @@ context "when building LOAD queries" do let(:from_url) {'http://example.org/data.rdf'} - it "should require a source URI" do + it "requires a source URI" do expect(subject.load(from_url).to_s).to eq "LOAD <#{from_url}>" end @@ -110,14 +110,14 @@ expect(subject.load(from_url)).to be_expects_statements end - it "should support the SILENT modifier" do + it "supports the SILENT modifier" do [subject.load(from_url).silent, subject.load(from_url, :silent => true)].each do |example| expect(example.to_s).to eq "LOAD SILENT <#{from_url}>" end end - it "should support the INTO GRAPH modifier" do + it "supports the INTO GRAPH modifier" do [subject.load(from_url).into(from_url), subject.load(from_url, :into => from_url)].each do |example| expect(example.to_s).to eq "LOAD <#{from_url}> INTO GRAPH <#{from_url}>" @@ -126,7 +126,7 @@ end context "when building CLEAR queries" do - it "should support the CLEAR GRAPH operation" do + it "supports the CLEAR GRAPH operation" do graph_uri = 'http://example.org/' [subject.clear.graph(graph_uri), subject.clear(:graph, graph_uri)].each do |example| @@ -134,19 +134,19 @@ end end - it "should support the CLEAR DEFAULT operation" do + it "supports the CLEAR DEFAULT operation" do [subject.clear.default, subject.clear(:default)].each do |example| expect(example.to_s).to eq "CLEAR DEFAULT" end end - it "should support the CLEAR NAMED operation" do + it "supports the CLEAR NAMED operation" do [subject.clear.named, subject.clear(:named)].each do |example| expect(example.to_s).to eq "CLEAR NAMED" end end - it "should support the CLEAR ALL operation" do + it "supports the CLEAR ALL operation" do [subject.clear.all, subject.clear(:all)].each do |example| expect(example.to_s).to eq "CLEAR ALL" end @@ -156,7 +156,7 @@ expect(subject.clear.all).not_to be_expects_statements end - it "should support the SILENT modifier" do + it "supports the SILENT modifier" do [subject.clear(:all).silent, subject.clear(:all, :silent => true)].each do |example| expect(example.to_s).to eq "CLEAR SILENT ALL" @@ -167,11 +167,11 @@ context "when building CREATE queries" do let(:graph_uri) {'http://example.org/'} - it "should require a graph URI" do + it "requires a graph URI" do expect(subject.create(graph_uri).to_s).to eq "CREATE GRAPH <#{graph_uri}>" end - it "should support the SILENT modifier" do + it "supports the SILENT modifier" do [subject.create(graph_uri).silent, subject.create(graph_uri, :silent => true)].each do |example| expect(example.to_s).to eq "CREATE SILENT GRAPH <#{graph_uri}>" @@ -184,7 +184,7 @@ end context "when building DROP queries" do - it "should support the DROP GRAPH operation" do + it "supports the DROP GRAPH operation" do graph_uri = 'http://example.org/' [subject.drop.graph(graph_uri), subject.drop(:graph, graph_uri)].each do |example| @@ -192,19 +192,19 @@ end end - it "should support the DROP DEFAULT operation" do + it "supports the DROP DEFAULT operation" do [subject.drop.default, subject.drop(:default)].each do |example| expect(example.to_s).to eq "DROP DEFAULT" end end - it "should support the DROP NAMED operation" do + it "supports the DROP NAMED operation" do [subject.drop.named, subject.drop(:named)].each do |example| expect(example.to_s).to eq "DROP NAMED" end end - it "should support the DROP ALL operation" do + it "supports the DROP ALL operation" do [subject.drop.all, subject.drop(:all)].each do |example| expect(example.to_s).to eq "DROP ALL" end @@ -214,7 +214,7 @@ expect(subject.drop.all).not_to be_expects_statements end - it "should support the SILENT modifier" do + it "supports the SILENT modifier" do [subject.drop(:all).silent, subject.drop(:all, :silent => true)].each do |example| expect(example.to_s).to eq "DROP SILENT ALL" From 336effde09f8959e69677f2582db9d4d90f934eb Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 15 Oct 2018 10:42:36 -0700 Subject: [PATCH 6/8] Run 2.2.2 on Travis. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0c30004f..0eacd252 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ gemfile: - Gemfile - Gemfile-pure rvm: - - 2.2 + - 2.2.2 - 2.3 - 2.4 - 2.5 From 8b2723ff950335469fa558b2998e9185f1cfcd55 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 1 Jul 2019 17:48:13 -0700 Subject: [PATCH 7/8] Remove jruby-openssl from Gemfiles. --- Gemfile | 1 - Gemfile-pure | 1 - 2 files changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index c7be335f..69ff4e30 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,6 @@ gemspec gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" gem 'rdf-aggregate-repo', git: "https://github.com/ruby-rdf/rdf-aggregate-repo", branch: "develop" gem 'sparql', git: "https://github.com/ruby-rdf/sparql", branch: "develop" -gem "jruby-openssl", platforms: :jruby gem "nokogiri", '~> 1.8' group :development, :test do diff --git a/Gemfile-pure b/Gemfile-pure index 1ab8f736..5307d93f 100644 --- a/Gemfile-pure +++ b/Gemfile-pure @@ -5,7 +5,6 @@ gemspec gem 'rdf', git: "https://github.com/ruby-rdf/rdf", branch: "develop" gem 'rdf-aggregate-repo', git: "https://github.com/ruby-rdf/rdf-aggregate-repo", branch: "develop" gem 'sparql', git: "https://github.com/ruby-rdf/sparql", branch: "develop" -gem "jruby-openssl", platforms: :jruby #gem "nokogiri", '~> 1.8' group :development, :test do From cc9812c8baed593e1d3b5c745ee3ec0ca84d1124 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 15 Dec 2019 17:23:06 -0800 Subject: [PATCH 8/8] Updates for 3.1 release and Ruby 2.7 calling sequences. --- .travis.yml | 12 +-- Gemfile | 4 +- Gemfile-pure | 4 +- README.md | 12 +-- VERSION | 2 +- lib/sparql/client.rb | 74 ++++++++-------- lib/sparql/client/query.rb | 43 +++++----- lib/sparql/client/repository.rb | 22 ++--- lib/sparql/client/update.rb | 55 ++++++------ sparql-client.gemspec | 18 ++-- spec/client_spec.rb | 144 ++++++++++++++++---------------- spec/query_spec.rb | 22 ++--- spec/spec_helper.rb | 2 +- spec/update_spec.rb | 14 ++-- 14 files changed, 211 insertions(+), 217 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0eacd252..2b531323 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,26 +1,20 @@ language: ruby bundler_args: --without debug script: "bundle exec rspec spec" -before_install: - - 'gem update --system --conservative || (gem i "rubygems-update:~>2.7" --no-document && update_rubygems)' - - 'gem update bundler --conservative' env: - CI=true gemfile: - Gemfile - Gemfile-pure rvm: - - 2.2.2 - - 2.3 - 2.4 - 2.5 - 2.6 - - jruby-9 - - rbx-3 + - 2.7 + - jruby cache: bundler sudo: false matrix: allow_failures: - - rvm: jruby-9 - - rvm: rbx-3 + - rvm: jruby dist: trusty diff --git a/Gemfile b/Gemfile index 69ff4e30..1f869739 100644 --- a/Gemfile +++ b/Gemfile @@ -15,8 +15,8 @@ group :development, :test do gem "rdf-xsd", git: "https://github.com/ruby-rdf/rdf-xsd", branch: "develop" gem 'sxp', git: "https://github.com/dryruby/sxp.rb", branch: "develop" gem "redcarpet", platform: :ruby - gem 'simplecov', require: false, platform: :mri - gem 'coveralls', require: false, platform: :mri + gem 'simplecov', platforms: :mri + gem 'coveralls', '~> 0.8', platforms: :mri end group :debug do diff --git a/Gemfile-pure b/Gemfile-pure index 5307d93f..4c744c55 100644 --- a/Gemfile-pure +++ b/Gemfile-pure @@ -15,8 +15,8 @@ group :development, :test do gem "rdf-xsd", git: "https://github.com/ruby-rdf/rdf-xsd", branch: "develop" gem 'sxp', git: "https://github.com/dryruby/sxp.rb", branch: "develop" gem "redcarpet", platform: :ruby - gem 'simplecov', require: false, platform: :mri - gem 'coveralls', require: false, platform: :mri + gem 'simplecov', platforms: :mri + gem 'coveralls', '~> 0.8', platforms: :mri end group :debug do diff --git a/README.md b/README.md index 8554ae1a..2650f5b8 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ sparql = SPARQL::Client.new("http://dbpedia.org/sparql", headers: {'User-Agent' ```ruby require 'sparql/client' -sparql = SPARQL::Client.new("http://dbpedia.org/sparql", { :graph => "http://dbpedia.org" }) +sparql = SPARQL::Client.new("http://dbpedia.org/sparql", { graph: "http://dbpedia.org" }) ``` @@ -123,11 +123,11 @@ sparql.delete_data(data) ## Dependencies -* [Ruby](http://ruby-lang.org/) (>= 2.2.2) -* [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.0) -* [Net::HTTP::Persistent](http://rubygems.org/gems/net-http-persistent) (~> 3.0) -* Soft dependency on [SPARQL](http://rubygems.org/gems/sparql) (~> 3.0) -* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.8) +* [Ruby](http://ruby-lang.org/) (>= 2.4) +* [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.1) +* [Net::HTTP::Persistent](http://rubygems.org/gems/net-http-persistent) (~> 3.1) +* Soft dependency on [SPARQL](http://rubygems.org/gems/sparql) (~> 3.1) +* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.10) ## Installation diff --git a/VERSION b/VERSION index cb2b00e4..fd2a0186 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.1 +3.1.0 diff --git a/lib/sparql/client.rb b/lib/sparql/client.rb index 3ea1830c..c2423de0 100644 --- a/lib/sparql/client.rb +++ b/lib/sparql/client.rb @@ -92,7 +92,7 @@ class ServerError < StandardError; end # # Defaults `User-Agent` header, unless one is specified. # @option options [Hash] :read_timeout - def initialize(url, options = {}, &block) + def initialize(url, **options, &block) case url when RDF::Queryable @url, @options = url, options.dup @@ -128,8 +128,8 @@ def close # # @param (see Query.ask) # @return [Query] - def ask(*args) - call_query_method(:ask, *args) + def ask(*args, **options) + call_query_method(:ask, *args, **options) end ## @@ -137,8 +137,8 @@ def ask(*args) # # @param (see Query.select) # @return [Query] - def select(*args) - call_query_method(:select, *args) + def select(*args, **options) + call_query_method(:select, *args, **options) end ## @@ -146,8 +146,8 @@ def select(*args) # # @param (see Query.describe) # @return [Query] - def describe(*args) - call_query_method(:describe, *args) + def describe(*args, **options) + call_query_method(:describe, *args, **options) end ## @@ -155,8 +155,8 @@ def describe(*args) # # @param (see Query.construct) # @return [Query] - def construct(*args) - call_query_method(:construct, *args) + def construct(*args, **options) + call_query_method(:construct, *args, **options) end ## @@ -179,15 +179,15 @@ def construct(*args) # client.insert_data(data) # # @example Inserting data into a named graph - # client.insert_data(data, :graph => "http://example.org/") + # client.insert_data(data, graph: "http://example.org/") # # @param [RDF::Enumerable] data # @param [Hash{Symbol => Object}] options # @option options [RDF::URI, String] :graph # @return [void] `self` # @see http://www.w3.org/TR/sparql11-update/#insertData - def insert_data(data, options = {}) - self.update(Update::InsertData.new(data, options)) + def insert_data(data, **options) + self.update(Update::InsertData.new(data, **options)) end ## @@ -200,15 +200,15 @@ def insert_data(data, options = {}) # client.delete_data(data) # # @example Deleting data from a named graph - # client.delete_data(data, :graph => "http://example.org/") + # client.delete_data(data, graph: "http://example.org/") # # @param [RDF::Enumerable] data # @param [Hash{Symbol => Object}] options # @option options [RDF::URI, String] :graph # @return [void] `self` # @see http://www.w3.org/TR/sparql11-update/#deleteData - def delete_data(data, options = {}) - self.update(Update::DeleteData.new(data, options)) + def delete_data(data, **options) + self.update(Update::DeleteData.new(data, **options)) end ## @@ -223,8 +223,8 @@ def delete_data(data, options = {}) # @option options [RDF::URI, String] :graph # @return [void] `self` # @see http://www.w3.org/TR/sparql11-update/#deleteInsert - def delete_insert(delete_graph, insert_graph = nil, where_graph = nil, options = {}) - self.update(Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, options)) + def delete_insert(delete_graph, insert_graph = nil, where_graph = nil, **options) + self.update(Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, **options)) end ## @@ -240,8 +240,8 @@ def delete_insert(delete_graph, insert_graph = nil, where_graph = nil, options = # @option options [Boolean] :silent # @return [void] `self` # @see http://www.w3.org/TR/sparql11-update/#clear - def clear_graph(graph_uri, options = {}) - self.clear(:graph, graph_uri, options) + def clear_graph(graph_uri, **options) + self.clear(:graph, graph_uri, **options) end ## @@ -267,7 +267,7 @@ def clear_graph(graph_uri, options = {}) # @option options [Boolean] :silent # @return [void] `self` # - # @overload clear(what, *arguments, options = {}) + # @overload clear(what, *arguments, **options) # @param [Symbol, #to_sym] what # @param [Array] arguments splat of other arguments to {Update::Clear}. # @param [Hash{Symbol => Object}] options @@ -281,9 +281,9 @@ def clear(what, *arguments) ## # @private - def call_query_method(meth, *args) + def call_query_method(meth, *args, **options) client = self - result = Query.send(meth, *args) + result = Query.send(meth, *args, **options) (class << result; self; end).send(:define_method, :execute) do client.query(self) end @@ -308,20 +308,20 @@ def nodes # @return [Array] # @raise [IOError] if connection is closed # @see http://www.w3.org/TR/sparql11-protocol/#query-operation - def query(query, options = {}) + def query(query, **options) @op = :query @alt_endpoint = options[:endpoint] case @url when RDF::Queryable require 'sparql' unless defined?(::SPARQL::Grammar) begin - SPARQL.execute(query, @url, options) + SPARQL.execute(query, @url, **options) rescue SPARQL::MalformedQuery $stderr.puts "error running #{query}: #{$!}" raise end else - parse_response(response(query, options), options) + parse_response(response(query, **options), **options) end end @@ -336,15 +336,15 @@ def query(query, options = {}) # @return [void] `self` # @raise [IOError] if connection is closed # @see http://www.w3.org/TR/sparql11-protocol/#update-operation - def update(query, options = {}) + def update(query, **options) @op = :update @alt_endpoint = options[:endpoint] case @url when RDF::Queryable require 'sparql' unless defined?(::SPARQL::Grammar) - SPARQL.execute(query, @url, options.merge(update: true)) + SPARQL.execute(query, @url, update: true, **options) else - response(query, options) + response(query, **options) end self end @@ -359,7 +359,7 @@ def update(query, options = {}) # @option options [Hash] :headers # @return [String] # @raise [IOError] if connection is closed - def response(query, options = {}) + def response(query, **options) headers = options[:headers] || @headers headers['Accept'] = options[:content_type] if options[:content_type] request(query, headers) do |response| @@ -380,7 +380,7 @@ def response(query, options = {}) # @param [Net::HTTPSuccess] response # @param [Hash{Symbol => Object}] options # @return [Object] - def parse_response(response, options = {}) + def parse_response(response, **options) case options[:content_type] || response.content_type when NilClass response.body @@ -395,7 +395,7 @@ def parse_response(response, options = {}) when RESULT_TSV self.class.parse_tsv_bindings(response.body, nodes) else - parse_rdf_serialization(response, options) + parse_rdf_serialization(response, **options) end end @@ -432,9 +432,9 @@ def self.parse_json_value(value, nodes = {}) when :uri RDF::URI.new(value['value']) when :literal - RDF::Literal.new(value['value'], :datatype => value['datatype'], :language => value['xml:lang']) + RDF::Literal.new(value['value'], datatype: value['datatype'], language: value['xml:lang']) when :'typed-literal' - RDF::Literal.new(value['value'], :datatype => value['datatype']) + RDF::Literal.new(value['value'], datatype: value['datatype']) else nil end end @@ -550,7 +550,7 @@ def self.parse_xml_value(value, nodes = {}) when :literal lang = value.respond_to?(:attr) ? value.attr('xml:lang') : value.attributes['xml:lang'] datatype = value.respond_to?(:attr) ? value.attr('datatype') : value.attributes['datatype'] - RDF::Literal.new(value.text, :language => lang, :datatype => datatype) + RDF::Literal.new(value.text, language: lang, datatype: datatype) else nil end end @@ -559,8 +559,8 @@ def self.parse_xml_value(value, nodes = {}) # @param [Net::HTTPSuccess] response # @param [Hash{Symbol => Object}] options # @return [RDF::Enumerable] - def parse_rdf_serialization(response, options = {}) - options = {:content_type => response.content_type} unless options[:content_type] + def parse_rdf_serialization(response, **options) + options = {content_type: response.content_type} unless options[:content_type] if reader = RDF::Reader.for(options) reader.new(response.body) else @@ -750,7 +750,7 @@ def request_method(query) # @see http://www.w3.org/TR/sparql11-protocol/#query-via-get def make_get_request(query, headers = {}) url = self.url.dup - url.query_values = (url.query_values || {}).merge(:query => query.to_s) + url.query_values = (url.query_values || {}).merge(query: query.to_s) set_url_default_graph url unless @options[:graph].nil? request = Net::HTTP::Get.new(url.request_uri, self.headers.merge(headers)) request diff --git a/lib/sparql/client/query.rb b/lib/sparql/client/query.rb index 97610544..d55c782c 100644 --- a/lib/sparql/client/query.rb +++ b/lib/sparql/client/query.rb @@ -26,8 +26,8 @@ class Query < RDF::Query # @param [Hash{Symbol => Object}] options (see {#initialize}) # @return [Query] # @see http://www.w3.org/TR/sparql11-query/#ask - def self.ask(options = {}) - self.new(:ask, options) + def self.ask(**options) + self.new(:ask, **options) end ## @@ -45,14 +45,13 @@ def self.ask(options = {}) # @param [Array] variables # @return [Query] # - # @overload self.select(*variables, options) + # @overload self.select(*variables, **options) # @param [Array] variables # @param [Hash{Symbol => Object}] options (see {#initialize}) # @return [Query] # @see http://www.w3.org/TR/sparql11-query/#select - def self.select(*variables) - options = variables.last.is_a?(Hash) ? variables.pop : {} - self.new(:select, options).select(*variables) + def self.select(*variables, **options) + self.new(:select, **options).select(*variables) end ## @@ -64,14 +63,13 @@ def self.select(*variables) # @param [Array] variables # @return [Query] # - # @overload self.describe(*variables, options) + # @overload self.describe(*variables, **options) # @param [Array] variables # @param [Hash{Symbol => Object}] options (see {#initialize}) # @return [Query] # @see http://www.w3.org/TR/sparql11-query/#describe - def self.describe(*variables) - options = variables.last.is_a?(Hash) ? variables.pop : {} - self.new(:describe, options).describe(*variables) + def self.describe(*variables, **options) + self.new(:describe, **options).describe(*variables) end ## @@ -83,19 +81,18 @@ def self.describe(*variables) # @param [Array] patterns # @return [Query] # - # @overload self.construct(*variables, options) + # @overload self.construct(*variables, **options) # @param [Array] patterns # @param [Hash{Symbol => Object}] options (see {#initialize}) # @return [Query] # @see http://www.w3.org/TR/sparql11-query/#construct - def self.construct(*patterns) - options = patterns.last.is_a?(Hash) ? patterns.pop : {} - self.new(:construct, options).construct(*patterns) # FIXME + def self.construct(*patterns, **options) + self.new(:construct, **options).construct(*patterns) # FIXME end ## # @param [Symbol, #to_s] form - # @overload self.construct(*variables, options) + # @overload self.construct(*variables, **options) # @param [Symbol, #to_s] form # @param [Hash{Symbol => Object}] options (see {Client#initialize}) # @option options [Hash{Symbol => Symbol}] :count @@ -104,10 +101,10 @@ def self.construct(*patterns) # # @yield [query] # @yieldparam [Query] - def initialize(form = :ask, options = {}, &block) + def initialize(form = :ask, **options, &block) @subqueries = [] @form = form.respond_to?(:to_sym) ? form.to_sym : form.to_s.to_sym - super([], options, &block) + super([], **options, &block) end ## @@ -131,11 +128,15 @@ def ask # @example SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class} # query.select(count: {uri: :c}).where([:uri, RDF.type, RDF::OWL.Class]) # - # @param [Array] variables + # @param [Array, Hash{Symbol => RDF::Query::Variable}] variables # @return [Query] # @see http://www.w3.org/TR/sparql11-query/#select def select(*variables) - @values = variables.map { |var| [var, RDF::Query::Variable.new(var)] } + @values = if variables.length == 1 && variables.first.is_a?(Hash) + variables.to_a + else + variables.map { |var| [var, RDF::Query::Variable.new(var)] } + end self end @@ -240,7 +241,7 @@ def select(*variables) # query.select.where([:s, :p, :o]).order_by(:o, :p) # # @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p) - # query.select.where([:s, :p, :o]).order_by(:o => :asc, :p => :desc) + # query.select.where([:s, :p, :o]).order_by(o: :asc, p: :desc) # # @param [Array] variables # @return [Query] @@ -727,7 +728,7 @@ def to_s buffer << 'ORDER BY' options[:order_by].map { |elem| case elem - # .order_by({ :var1 => :asc, :var2 => :desc}) + # .order_by({ var1: :asc, var2: :desc}) when Hash elem.each { |key, val| # check provided values diff --git a/lib/sparql/client/repository.rb b/lib/sparql/client/repository.rb index 8bd07821..136d0e89 100644 --- a/lib/sparql/client/repository.rb +++ b/lib/sparql/client/repository.rb @@ -14,9 +14,9 @@ class Repository < RDF::Repository def initialize(uri: nil, **options, &block) raise ArgumentError, "uri is a required parameter" unless uri @options = options.merge(uri: uri) - @update_client = SPARQL::Client.new(options.delete(:update_endpoint), options) if options[:update_endpoint] - @client = SPARQL::Client.new(uri, options) - super(@options, &block) + @update_client = SPARQL::Client.new(options.delete(:update_endpoint), **options) if options[:update_endpoint] + @client = SPARQL::Client.new(uri, **options) + super(**@options, &block) end ## @@ -115,7 +115,7 @@ def has_object?(object) # @see RDF::Repository#each_subject? def each_subject(&block) if block_given? - client.select(:s, :distinct => true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:s]) } + client.select(:s, distinct: true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:s]) } end enum_subject end @@ -129,7 +129,7 @@ def each_subject(&block) # @see RDF::Repository#each_predicate? def each_predicate(&block) if block_given? - client.select(:p, :distinct => true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:p]) } + client.select(:p, distinct: true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:p]) } end enum_predicate end @@ -143,7 +143,7 @@ def each_predicate(&block) # @see RDF::Repository#each_object? def each_object(&block) if block_given? - client.select(:o, :distinct => true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:o]) } + client.select(:o, distinct: true).where([:s, :p, :o]).each_solution { |solution| block.call(solution[:o]) } end enum_object end @@ -262,10 +262,10 @@ def delete(*statements) # @return [void] ignored # @see RDF::Queryable#query # @see RDF::Query#execute - def query_execute(query, options = {}, &block) + def query_execute(query, **options, &block) return nil unless block_given? - q = SPARQL::Client::Query.select(query.variables).where(*query.patterns) - client.query(q, options).each do |solution| + q = SPARQL::Client::Query.select(query.variables, **{}).where(*query.patterns) + client.query(q, **options).each do |solution| yield solution end end @@ -275,7 +275,7 @@ def query_execute(query, options = {}, &block) # # @example # repository.query([nil, RDF::DOAP.developer, nil]) - # repository.query(:predicate => RDF::DOAP.developer) + # repository.query({predicate: RDF::DOAP.developer}) # # @todo This should use basic SPARQL query mechanism. # @@ -284,7 +284,7 @@ def query_execute(query, options = {}, &block) # @yield [statement] # @yieldparam [Statement] # @return [Enumerable] - def query_pattern(pattern, options = {}, &block) + def query_pattern(pattern, **options, &block) pattern = pattern.dup pattern.subject ||= RDF::Query::Variable.new pattern.predicate ||= RDF::Query::Variable.new diff --git a/lib/sparql/client/update.rb b/lib/sparql/client/update.rb index 3acdbce9..fa014b18 100644 --- a/lib/sparql/client/update.rb +++ b/lib/sparql/client/update.rb @@ -12,12 +12,12 @@ module Update # insert_data(data) # # @example INSERT DATA \{ GRAPH \{\}\} - # insert_data(RDF::Graph.new, :graph => 'http://example.org/') + # insert_data(RDF::Graph.new, graph: 'http://example.org/') # insert_data(RDF::Graph.new).graph('http://example.org/') # # @param (see InsertData#initialize) - def self.insert_data(*arguments) - InsertData.new(*arguments) + def self.insert_data(*arguments, **options) + InsertData.new(*arguments, **options) end ## @@ -30,12 +30,12 @@ def self.insert_data(*arguments) # delete_data(data) # # @example DELETE DATA \{ GRAPH \{\}\} - # delete_data(RDF::Graph.new, :graph => 'http://example.org/') + # delete_data(RDF::Graph.new, graph: 'http://example.org/') # delete_data(RDF::Graph.new).graph('http://example.org/') # # @param (see DeleteData#initialize) - def self.delete_data(*arguments) - DeleteData.new(*arguments) + def self.delete_data(*arguments, **options) + DeleteData.new(*arguments, **options) end ## @@ -53,8 +53,8 @@ def self.delete_data(*arguments) # load(RDF::URI(http://example.org/data.rdf), into: RDF::URI(http://example.org/data.rdf)) # # @param (see Load#initialize) - def self.load(*arguments) - Load.new(*arguments) + def self.load(*arguments, **options) + Load.new(*arguments, **options) end ## @@ -81,8 +81,8 @@ def self.load(*arguments) # clear(:all, silent: true) # # @param (see Clear#initialize) - def self.clear(*arguments) - Clear.new(*arguments) + def self.clear(*arguments, **options) + Clear.new(*arguments, **options) end ## @@ -96,8 +96,8 @@ def self.clear(*arguments) # create(RDF::URI(http://example.org/data.rdf), silent: true) # # @param (see Create#initialize) - def self.create(*arguments) - Create.new(*arguments) + def self.create(*arguments, **options) + Create.new(*arguments, **options) end ## @@ -124,15 +124,15 @@ def self.create(*arguments) # drop(:all, silent: true) # # @param (see Drop#initialize) - def self.drop(*arguments) - Drop.new(*arguments) + def self.drop(*arguments, **options) + Drop.new(*arguments, **options) end class Operation attr_reader :options - def initialize(*arguments) - @options = arguments.last.is_a?(Hash) ? arguments.pop.dup : {} + def initialize(*arguments, **options) + @options = options.dup unless arguments.empty? send(arguments.shift, *arguments) end @@ -171,9 +171,9 @@ class InsertData < Operation # # @param [Array, RDF::Enumerable] data # @param [Hash{Symbol => Object}] options - def initialize(data, options = {}) + def initialize(data, **options) @data = data - super(options) + super(**options) end ## @@ -221,9 +221,9 @@ class DeleteData < Operation # # @param [Array, RDF::Enumerable] data # @param [Hash{Symbol => Object}] options - def initialize(data, options = {}) + def initialize(data, **options) @data = data - super(options) + super(**options) end ## @@ -253,11 +253,11 @@ class DeleteInsert < Operation attr_reader :delete_graph attr_reader :where_graph - def initialize(_delete_graph, _insert_graph = nil, _where_graph = nil, options = {}) + def initialize(_delete_graph, _insert_graph = nil, _where_graph = nil, **options) @delete_graph = _delete_graph @insert_graph = _insert_graph @where_graph = _where_graph - super(options) + super(**options) end ## @@ -324,11 +324,10 @@ class Load < Operation # @param [Hash{Symbol => Object}] options # @option [RDF::URI] :into # @option [Boolean] :silent - def initialize(from, options = {}) - options = options.dup + def initialize(from, into: nil,**options) @from = RDF::URI(from) - @into = RDF::URI(options.delete(:into)) if options[:into] - super(options) + @into = RDF::URI(into) if into + super(**options) end ## @@ -420,9 +419,9 @@ class Create < Operation attr_reader :uri # @param [Hash{Symbol => Object}] options - def initialize(uri, options = {}) + def initialize(uri, **options) @uri = RDF::URI(uri) - super(options) + super(**options) end def to_s diff --git a/sparql-client.gemspec b/sparql-client.gemspec index 458c8bd4..1baa1ff1 100755 --- a/sparql-client.gemspec +++ b/sparql-client.gemspec @@ -22,16 +22,16 @@ Gem::Specification.new do |gem| gem.bindir = %q(bin) gem.require_paths = %w(lib) - gem.required_ruby_version = '>= 2.2.2' + gem.required_ruby_version = '>= 2.4' gem.requirements = [] - gem.add_runtime_dependency 'rdf', '~> 3.0' - gem.add_runtime_dependency 'net-http-persistent', '~> 3.0' - gem.add_development_dependency 'rdf-spec', '~> 3.0' - gem.add_development_dependency 'sparql', '~> 3.0' - gem.add_development_dependency 'rspec', '~> 3.7' - gem.add_development_dependency 'rspec-its', '~> 1.2' - gem.add_development_dependency 'webmock', '~> 3.1' - gem.add_development_dependency 'yard' , '~> 0.9.12' + gem.add_runtime_dependency 'rdf', '~> 3.1' + gem.add_runtime_dependency 'net-http-persistent', '~> 3.1' + gem.add_development_dependency 'rdf-spec', '~> 3.1' + gem.add_development_dependency 'sparql', '~> 3.1' + gem.add_development_dependency 'rspec', '~> 3.9' + gem.add_development_dependency 'rspec-its', '~> 1.3' + gem.add_development_dependency 'webmock', '~> 3.7' + gem.add_development_dependency 'yard' , '~> 0.9.20' gem.post_install_message = nil end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 8bc5b0d8..3a33d225 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -57,7 +57,7 @@ def response(header) it "handles successful response with plain header" do expect(subject).to receive(:request).and_yield response('text/plain') - expect(RDF::Reader).to receive(:for).with(:content_type => 'text/plain').and_call_original + expect(RDF::Reader).to receive(:for).with(content_type: 'text/plain').and_call_original subject.query(query) end @@ -93,7 +93,7 @@ def response(header) it "handles successful response with overridden XML header" do expect(subject).to receive(:request).and_yield response(SPARQL::Client::RESULT_XML) expect(subject.class).to receive(:parse_json_bindings) - subject.query(query, :content_type => SPARQL::Client::RESULT_JSON) + subject.query(query, content_type: SPARQL::Client::RESULT_JSON) end it "handles successful response with no content type" do @@ -103,27 +103,27 @@ def response(header) it "handles successful response with overridden plain header" do expect(subject).to receive(:request).and_yield response('text/plain') - expect(RDF::Reader).to receive(:for).with(:content_type => 'text/turtle').and_call_original - subject.query(query, :content_type => 'text/turtle') + expect(RDF::Reader).to receive(:for).with(content_type: 'text/turtle').and_call_original + subject.query(query, content_type: 'text/turtle') end it "handles successful response with custom headers" do expect(subject).to receive(:request).with(anything, "Authorization" => "Basic XXX=="). and_yield response('text/plain') - subject.query(query, :headers => {"Authorization" => "Basic XXX=="}) + subject.query(query, headers: {"Authorization" => "Basic XXX=="}) end it "handles successful response with initial custom headers" do - options = {:headers => {"Authorization" => "Basic XXX=="}, :method => :get} - client = SPARQL::Client.new('http://data.linkedmdb.org/sparql', options) - client.instance_variable_set :@http, double(:request => response('text/plain')) + options = {headers: {"Authorization" => "Basic XXX=="}, method: :get} + client = SPARQL::Client.new('http://data.linkedmdb.org/sparql', **options) + client.instance_variable_set :@http, double(request: response('text/plain')) expect(Net::HTTP::Get).to receive(:new).with(anything, hash_including(options[:headers])) client.query(query) end it "enables overriding the http method" do stub_request(:get, "http://data.linkedmdb.org/sparql?query=DESCRIBE%20?kb%20WHERE%20%7B%20?kb%20%3Chttp://data.linkedmdb.org/resource/movie/actor_name%3E%20%22Kevin%20Bacon%22%20.%20%7D"). - to_return(:status => 200, :body => "", :headers => { 'Content-Type' => 'application/n-triples'}) + to_return(status: 200, body: "", headers: { 'Content-Type' => 'application/n-triples'}) allow(subject).to receive(:request_method).with(query).and_return(:get) expect(subject).to receive(:make_get_request).and_call_original subject.query(query) @@ -132,16 +132,16 @@ def response(header) it "supports international characters in response body" do client = SPARQL::Client.new('http://dbpedia.org/sparql') json = { - :results => { - :bindings => [ - :name => {:type => :literal, "xml:lang" => "jp", :value => "東京"} + results: { + bindings: [ + name: {type: :literal, "xml:lang" => "jp", value: "東京"} ], } }.to_json WebMock.stub_request(:any, 'http://dbpedia.org/sparql'). - to_return(:body => json, :status => 200, :headers => { 'Content-Type' => SPARQL::Client::RESULT_JSON}) + to_return(body: json, status: 200, headers: { 'Content-Type' => SPARQL::Client::RESULT_JSON}) query = "SELECT ?name WHERE { ?name }" - result = client.query(query, :content_type => SPARQL::Client::RESULT_JSON).first + result = client.query(query, content_type: SPARQL::Client::RESULT_JSON).first expect(result[:name].to_s).to eq "東京" end @@ -153,20 +153,20 @@ def response(header) context "Redirects" do before do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 303, :headers => { 'Location' => 'http://sparql.linkedmdb.org/sparql' }) + to_return(body: '{}', status: 303, headers: { 'Location' => 'http://sparql.linkedmdb.org/sparql' }) end it 'follows redirects' do WebMock.stub_request(:any, 'http://sparql.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { :content_type => SPARQL::Client::RESULT_JSON}) + to_return(body: '{}', status: 200, headers: { content_type: SPARQL::Client::RESULT_JSON}) subject.query(ask_query) expect(WebMock).to have_requested(:post, "http://sparql.linkedmdb.org/sparql"). - with(:body => 'query=ASK+WHERE+%7B+%3Fkb+%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E+%22Kevin+Bacon%22+.+%7D') + with(body: 'query=ASK+WHERE+%7B+%3Fkb+%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E+%22Kevin+Bacon%22+.+%7D') end it 'raises an error on infinate redirects' do WebMock.stub_request(:any, 'http://sparql.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 303, :headers => { 'Location' => 'http://sparql.linkedmdb.org/sparql' }) + to_return(body: '{}', status: 303, headers: { 'Location' => 'http://sparql.linkedmdb.org/sparql' }) expect{ subject.query(ask_query) }.to raise_error SPARQL::Client::ServerError end end @@ -174,85 +174,85 @@ def response(header) context "Accept Header" do it "uses application/sparql-results+json for ASK" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) subject.query(ask_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) + with(headers: {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) end it "uses application/n-triples for CONSTRUCT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) + to_return(body: '', status: 200, headers: { 'Content-Type' => 'application/n-triples'}) subject.query(construct_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) + with(headers: {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end it "uses application/n-triples for DESCRIBE" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '', :status => 200, :headers => { 'Content-Type' => 'application/n-triples'}) + to_return(body: '', status: 200, headers: { 'Content-Type' => 'application/n-triples'}) subject.query(describe_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) + with(headers: {'Accept'=>'application/n-triples, text/plain, */*;q=0.1'}) end it "uses application/sparql-results+json for SELECT" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) subject.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) + with(headers: {'Accept'=>'application/sparql-results+json, application/sparql-results+xml, text/boolean, text/tab-separated-values;q=0.8, text/csv;q=0.2, */*;q=0.1'}) end end context 'User-Agent header' do it "uses default if not specified" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) subject.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'User-Agent' => "Ruby SPARQL::Client/#{SPARQL::Client::VERSION}"}) + with(headers: {'User-Agent' => "Ruby SPARQL::Client/#{SPARQL::Client::VERSION}"}) end it "uses user-provided value in query" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) subject.query(select_query, headers: {'User-Agent' => 'Foo'}) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'User-Agent' => "Foo"}) + with(headers: {'User-Agent' => "Foo"}) end it "uses user-provided value in initialization" do client = SPARQL::Client.new('http://data.linkedmdb.org/sparql', headers: {'User-Agent' => 'Foo'}) WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) client.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql"). - with(:headers => {'User-Agent' => "Foo"}) + with(headers: {'User-Agent' => "Foo"}) end end context "Alternative Endpoint" do it "uses the default endpoint if no alternative endpoint is provided" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '', :status => 200) + to_return(body: '', status: 200) subject.update(update_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql") end it "uses the alternative endpoint if provided" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/alternative'). - to_return(:body => '', :status => 200) - subject.update(update_query, { endpoint: "http://data.linkedmdb.org/alternative" }) + to_return(body: '', status: 200) + subject.update(update_query, endpoint: "http://data.linkedmdb.org/alternative") expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/alternative") end it "does not use the alternative endpoint for a select query" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => '', :status => 200) + to_return(body: '', status: 200) WebMock.stub_request(:any, 'http://data.linkedmdb.org/alternative'). - to_return(:body => '', :status => 200) - subject.update(update_query, { endpoint: "http://data.linkedmdb.org/alternative" }) + to_return(body: '', status: 200) + subject.update(update_query, endpoint: "http://data.linkedmdb.org/alternative") expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/alternative") subject.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql") @@ -260,47 +260,47 @@ def response(header) end context "with multiple Graphs" do - let(:get_graph_client){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', {:method => 'get', :graph => 'http://data.linkedmdb.org/graph1'}) } - let(:post_graph_client10){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', {:method => 'post', :graph => 'http://data.linkedmdb.org/graph1', :protocol => '1.0'}) } - let(:post_graph_client11){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', {:method => 'post', :graph => 'http://data.linkedmdb.org/graph1', :protocol => '1.1'}) } + let(:get_graph_client){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', method: 'get', graph: 'http://data.linkedmdb.org/graph1') } + let(:post_graph_client10){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', method: 'post', graph: 'http://data.linkedmdb.org/graph1', protocol: '1.0') } + let(:post_graph_client11){ SPARQL::Client.new('http://data.linkedmdb.org/sparql', method: 'post', graph: 'http://data.linkedmdb.org/graph1', protocol: '1.1') } it "should create 'query via GET' requests" do WebMock.stub_request(:get, 'http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1&query=SELECT%20%3Fkb%20WHERE%20%7B%20%3Fkb%20%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E%20%22Kevin%20Bacon%22%20.%20%7D'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) get_graph_client.query(select_query) expect(WebMock).to have_requested(:get, "http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1&query=SELECT%20%3Fkb%20WHERE%20%7B%20%3Fkb%20%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E%20%22Kevin%20Bacon%22%20.%20%7D") end it "should create 'query via URL-encoded Post' requests" do WebMock.stub_request(:post, 'http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) post_graph_client10.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1"). - with(:body => "query=SELECT+%3Fkb+WHERE+%7B+%3Fkb+%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E+%22Kevin+Bacon%22+.+%7D&default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1") + with(body: "query=SELECT+%3Fkb+WHERE+%7B+%3Fkb+%3Chttp%3A%2F%2Fdata.linkedmdb.org%2Fresource%2Fmovie%2Factor_name%3E+%22Kevin+Bacon%22+.+%7D&default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1") end it "should create 'query via Post directly' requests" do WebMock.stub_request(:post, 'http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1'). - to_return(:body => '{}', :status => 200, :headers => { 'Content-Type' => 'application/sparql-results+json'}) + to_return(body: '{}', status: 200, headers: { 'Content-Type' => 'application/sparql-results+json'}) post_graph_client11.query(select_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql?default-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1"). - with(:body => select_query) + with(body: select_query) end it "should create requests for 'update via URL-encoded POST'" do WebMock.stub_request(:post, 'http://data.linkedmdb.org/sparql?using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1'). - to_return(:body => '{}', :status => 200) + to_return(body: '{}', status: 200) post_graph_client10.update(update_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql?using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1"). - with(:body => "update=DELETE+%7B%3Fs+%3Fp+%3Fo%7D+WHERE+%7B%7D&using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1") + with(body: "update=DELETE+%7B%3Fs+%3Fp+%3Fo%7D+WHERE+%7B%7D&using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1") end it "should create requests for 'update via POST directly'" do WebMock.stub_request(:post, 'http://data.linkedmdb.org/sparql?using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1'). - to_return(:body => '{}', :status => 200) + to_return(body: '{}', status: 200) post_graph_client11.update(update_query) expect(WebMock).to have_requested(:post, "http://data.linkedmdb.org/sparql?using-graph-uri=http%3A%2F%2Fdata.linkedmdb.org%2Fgraph1"). - with(:body => update_query) + with(body: update_query) end end @@ -315,7 +315,7 @@ def response(header) }.each do |test, params| it "detects #{test}" do WebMock.stub_request(:any, 'http://data.linkedmdb.org/sparql'). - to_return(:body => 'the body', :status => params[:status], headers: {'Content-Type' => 'text/plain'}) + to_return(body: 'the body', status: params[:status], headers: {'Content-Type' => 'text/plain'}) expect { subject.query(select_query) }.to raise_error(params[:error], "the body Processing query #{select_query}") @@ -331,7 +331,7 @@ def response(header) subject {SPARQL::Client.new(repo)} it "queries repository" do - expect(SPARQL).to receive(:execute).with(query, repo, {}) + expect(SPARQL).to receive(:execute).with(query, repo, any_args) subject.query(query) end @@ -384,11 +384,11 @@ def response(header) solutions = SPARQL::Client::parse_xml_bindings(xml, nodes) expect(solutions).to eq RDF::Query::Solutions.new([ RDF::Query::Solution.new( - :x => RDF::Node.new("r2"), - :hpage => RDF::URI.new("http://work.example.org/bob/"), - :name => RDF::Literal.new("Bob", :language => "en"), - :age => RDF::Literal.new("30", :datatype => "http://www.w3.org/2001/XMLSchema#integer"), - :mbox => RDF::URI.new("mailto:bob@work.example.org"), + x: RDF::Node.new("r2"), + hpage: RDF::URI.new("http://work.example.org/bob/"), + name: RDF::Literal.new("Bob", language: "en"), + age: RDF::Literal.new("30", datatype: "http://www.w3.org/2001/XMLSchema#integer"), + mbox: RDF::URI.new("mailto:bob@work.example.org"), ) ]) expect(solutions[0]["x"]).to eq nodes["r2"] @@ -412,11 +412,11 @@ def response(header) solutions = SPARQL::Client::parse_json_bindings(xml, nodes) expect(solutions).to eq RDF::Query::Solutions.new([ RDF::Query::Solution.new( - :x => RDF::Node.new("r2"), - :hpage => RDF::URI.new("http://work.example.org/bob/"), - :name => RDF::Literal.new("Bob", :language => "en"), - :age => RDF::Literal.new("30", :datatype => "http://www.w3.org/2001/XMLSchema#integer"), - :mbox => RDF::URI.new("mailto:bob@work.example.org"), + x: RDF::Node.new("r2"), + hpage: RDF::URI.new("http://work.example.org/bob/"), + name: RDF::Literal.new("Bob", language: "en"), + age: RDF::Literal.new("30", datatype: "http://www.w3.org/2001/XMLSchema#integer"), + mbox: RDF::URI.new("mailto:bob@work.example.org"), ) ]) expect(solutions[0]["x"]).to eq nodes["r2"] @@ -439,11 +439,11 @@ def response(header) nodes = {} solutions = SPARQL::Client::parse_csv_bindings(csv, nodes) expect(solutions).to eq RDF::Query::Solutions.new([ - RDF::Query::Solution.new(:x => RDF::URI("http://example/x"), - :literal => RDF::Literal('String-with-dquote"')), - RDF::Query::Solution.new(:x => RDF::Node.new("b0"), :literal => RDF::Literal("Blank node")), - RDF::Query::Solution.new(:x => RDF::Literal(""), :literal => RDF::Literal("Missing 'x'")), - RDF::Query::Solution.new(:x => RDF::Literal(""), :literal => RDF::Literal("")), + RDF::Query::Solution.new(x: RDF::URI("http://example/x"), + literal: RDF::Literal('String-with-dquote"')), + RDF::Query::Solution.new(x: RDF::Node.new("b0"), literal: RDF::Literal("Blank node")), + RDF::Query::Solution.new(x: RDF::Literal(""), literal: RDF::Literal("Missing 'x'")), + RDF::Query::Solution.new(x: RDF::Literal(""), literal: RDF::Literal("")), ]) expect(solutions[1]["x"]).to eq nodes["b0"] end @@ -455,11 +455,11 @@ def response(header) nodes = {} solutions = SPARQL::Client::parse_tsv_bindings(tsv, nodes) expect(solutions).to eq RDF::Query::Solutions.new([ - RDF::Query::Solution.new(:x => RDF::URI("http://example/x"), - :literal => RDF::Literal('String-with-dquote"')), - RDF::Query::Solution.new(:x => RDF::Node.new("blank0"), :literal => RDF::Literal("Blank node")), - RDF::Query::Solution.new(:x => RDF::Node("blank1"), :literal => RDF::Literal.new("String-with-lang", :language => "en")), - RDF::Query::Solution.new(:x => RDF::Node("blank1"), :literal => RDF::Literal::Integer.new("123")), + RDF::Query::Solution.new(x: RDF::URI("http://example/x"), + literal: RDF::Literal('String-with-dquote"')), + RDF::Query::Solution.new(x: RDF::Node.new("blank0"), literal: RDF::Literal("Blank node")), + RDF::Query::Solution.new(x: RDF::Node("blank1"), literal: RDF::Literal.new("String-with-lang", language: "en")), + RDF::Query::Solution.new(x: RDF::Node("blank1"), literal: RDF::Literal::Integer.new("123")), ]) expect(solutions[1]["x"]).to eq nodes["blank0"] end diff --git a/spec/query_spec.rb b/spec/query_spec.rb index bcac1fa9..d3cc31d8 100644 --- a/spec/query_spec.rb +++ b/spec/query_spec.rb @@ -100,13 +100,13 @@ end it "supports DISTINCT" do - expect(subject.select(:s, :distinct => true).where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT ?s WHERE { ?s ?p ?o . }" + expect(subject.select(:s, distinct: true).where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT ?s WHERE { ?s ?p ?o . }" expect(subject.select(:s).distinct.where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT ?s WHERE { ?s ?p ?o . }" expect(subject.select.distinct.where([:s, :p, :o]).to_s).to eq "SELECT DISTINCT * WHERE { ?s ?p ?o . }" end it "supports REDUCED" do - expect(subject.select(:s, :reduced => true).where([:s, :p, :o]).to_s).to eq "SELECT REDUCED ?s WHERE { ?s ?p ?o . }" + expect(subject.select(:s, reduced: true).where([:s, :p, :o]).to_s).to eq "SELECT REDUCED ?s WHERE { ?s ?p ?o . }" expect(subject.select(:s).reduced.where([:s, :p, :o]).to_s).to eq "SELECT REDUCED ?s WHERE { ?s ?p ?o . }" end @@ -116,11 +116,11 @@ end it "supports COUNT" do - expect(subject.select(:count => { :s => :c }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" - expect(subject.select(:count => { :s => :c }, :distinct => true).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(DISTINCT ?s) AS ?c ) WHERE { ?s ?p ?o . }" - expect(subject.select(:count => { :s => '?c' }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" - expect(subject.select(:count => { '?s' => '?c' }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" - expect(subject.select(:o, :count => { :s => :c }).where([:s, :p, :o]).to_s).to eq "SELECT ?o ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" + expect(subject.select(count: { s: :c }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" + expect(subject.select(count: { s: :c }, distinct: true).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(DISTINCT ?s) AS ?c ) WHERE { ?s ?p ?o . }" + expect(subject.select(count: { s: '?c' }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" + expect(subject.select(count: { '?s' => '?c' }).where([:s, :p, :o]).to_s).to eq "SELECT ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" + expect(subject.select(:o, count: { s: :c }).where([:s, :p, :o]).to_s).to eq "SELECT ?o ( COUNT(?s) AS ?c ) WHERE { ?s ?p ?o . }" end it "supports VALUES" do @@ -142,9 +142,9 @@ expect(subject.select.where([:s, :p, :o]).order_by('?o').to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o" expect(subject.select.where([:s, :p, :o]).order_by('ASC(?o)').to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" expect(subject.select.where([:s, :p, :o]).order_by('DESC(?o)').to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" - expect(subject.select.where([:s, :p, :o]).order_by(:o => :asc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" - expect(subject.select.where([:s, :p, :o]).order_by(:o => :desc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" - expect(subject.select.where([:s, :p, :o]).order_by(:o => :asc, :p => :desc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p)" + expect(subject.select.where([:s, :p, :o]).order_by(o: :asc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" + expect(subject.select.where([:s, :p, :o]).order_by(o: :desc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" + expect(subject.select.where([:s, :p, :o]).order_by(o: :asc, p: :desc).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p)" expect(subject.select.where([:s, :p, :o]).order_by([:o, :asc]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)" expect(subject.select.where([:s, :p, :o]).order_by([:o, :desc]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)" expect(subject.select.where([:s, :p, :o]).order_by([:o, :asc], [:p, :desc]).to_s).to eq "SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p)" @@ -153,7 +153,7 @@ expect { subject.select.where([:s, :p, :o]).order_by([:o]).to_s }.to raise_error(ArgumentError) expect { subject.select.where([:s, :p, :o]).order_by([:o, :csa]).to_s }.to raise_error(ArgumentError) expect { subject.select.where([:s, :p, :o]).order_by([:o, :asc, 42]).to_s }.to raise_error(ArgumentError) - expect { subject.select.where([:s, :p, :o]).order_by(:o => 42).to_s }.to raise_error(ArgumentError) + expect { subject.select.where([:s, :p, :o]).order_by(o: 42).to_s }.to raise_error(ArgumentError) expect { subject.select.where([:s, :p, :o]).order_by(42 => :asc).to_s }.to raise_error(ArgumentError) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8b8594fe..ec964673 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -20,6 +20,6 @@ RSpec.configure do |config| config.include(RDF::Spec::Matchers) - config.filter_run :focus => true + config.filter_run focus: true config.run_all_when_everything_filtered = true end diff --git a/spec/update_spec.rb b/spec/update_spec.rb index b1df03b4..16459364 100644 --- a/spec/update_spec.rb +++ b/spec/update_spec.rb @@ -64,7 +64,7 @@ end it "supports the GRAPH modifier" do - [subject.insert_data(RDF::Graph.new, :graph => 'http://example.org/'), + [subject.insert_data(RDF::Graph.new, graph: 'http://example.org/'), subject.insert_data(RDF::Graph.new).graph('http://example.org/')].each do |example| expect(example.to_s).to eq "INSERT DATA { GRAPH {\n}}\n" end @@ -88,7 +88,7 @@ end it "supports the GRAPH modifier" do - [subject.delete_data(RDF::Graph.new, :graph => 'http://example.org/'), + [subject.delete_data(RDF::Graph.new, graph: 'http://example.org/'), subject.delete_data(RDF::Graph.new).graph('http://example.org/')].each do |example| expect(example.to_s).to eq "DELETE DATA { GRAPH {\n}}\n" end @@ -112,14 +112,14 @@ it "supports the SILENT modifier" do [subject.load(from_url).silent, - subject.load(from_url, :silent => true)].each do |example| + subject.load(from_url, silent: true)].each do |example| expect(example.to_s).to eq "LOAD SILENT <#{from_url}>" end end it "supports the INTO GRAPH modifier" do [subject.load(from_url).into(from_url), - subject.load(from_url, :into => from_url)].each do |example| + subject.load(from_url, into: from_url)].each do |example| expect(example.to_s).to eq "LOAD <#{from_url}> INTO GRAPH <#{from_url}>" end end @@ -158,7 +158,7 @@ it "supports the SILENT modifier" do [subject.clear(:all).silent, - subject.clear(:all, :silent => true)].each do |example| + subject.clear(:all, silent: true)].each do |example| expect(example.to_s).to eq "CLEAR SILENT ALL" end end @@ -173,7 +173,7 @@ it "supports the SILENT modifier" do [subject.create(graph_uri).silent, - subject.create(graph_uri, :silent => true)].each do |example| + subject.create(graph_uri, silent: true)].each do |example| expect(example.to_s).to eq "CREATE SILENT GRAPH <#{graph_uri}>" end end @@ -216,7 +216,7 @@ it "supports the SILENT modifier" do [subject.drop(:all).silent, - subject.drop(:all, :silent => true)].each do |example| + subject.drop(:all, silent: true)].each do |example| expect(example.to_s).to eq "DROP SILENT ALL" end end