From 06cdb76670763fd60f6dba71e385a98867c87ac1 Mon Sep 17 00:00:00 2001 From: Bob Aman Date: Fri, 27 Jan 2012 17:57:57 +0300 Subject: [PATCH] Updated to replace httpadapter with faraday. --- CHANGELOG.md | 45 +-- README.md | 9 +- bin/google-api | 15 +- google-api-client.gemspec | 46 +-- lib/google/api_client.rb | 310 +++++++++--------- lib/google/api_client/discovery/method.rb | 6 +- lib/google/api_client/parser.rb | 60 ---- .../api_client/parsers/json/error_parser.rb | 35 -- .../api_client/parsers/json/pagination.rb | 41 --- lib/google/api_client/parsers/json_parser.rb | 120 ------- lib/google/api_client/reference.rb | 66 ++-- lib/google/api_client/result.rb | 12 +- lib/google/api_client/version.rb | 2 +- spec/google/api_client/discovery_spec.rb | 88 ++--- .../api_client/parsers/json_parser_spec.rb | 55 ---- spec/google/api_client_spec.rb | 31 +- tasks/gem.rake | 6 +- tasks/wiki.rake | 13 +- tasks/yard.rake | 2 +- 19 files changed, 338 insertions(+), 624 deletions(-) delete mode 100644 lib/google/api_client/parser.rb delete mode 100644 lib/google/api_client/parsers/json/error_parser.rb delete mode 100644 lib/google/api_client/parsers/json/pagination.rb delete mode 100644 lib/google/api_client/parsers/json_parser.rb delete mode 100644 spec/google/api_client/parsers/json_parser_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 10148823a..6aac71075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,36 +1,43 @@ +# 0.4.0 + +* Replaced httpadapter gem dependency with faraday +* Replaced json gem dependency with multi_json +* Fixed /dev/null issues on Windows +* Repeated parameters now work + # 0.3.0 -* updated to use v1 of the discovery API -* updated to use httpadapter 1.0.0 -* added OAuth 2 support to the command line tool -* renamed some switches in the command line tool -* added additional configuration capabilities -* fixed a few deprecation warnings from dependencies -* added gemspec to source control +* Updated to use v1 of the discovery API +* Updated to use httpadapter 1.0.0 +* Added OAuth 2 support to the command line tool +* Renamed some switches in the command line tool +* Added additional configuration capabilities +* Fixed a few deprecation warnings from dependencies +* Added gemspec to source control # 0.2.0 -* updated to use v1 of the discovery API -* updated to use httpadapter 1.0.0 -* added OAuth 2 support to the command line tool -* renamed some switches in the command line tool -* added additional configuration capabilities +* Updated to use v1 of the discovery API +* Updated to use httpadapter 1.0.0 +* Added OAuth 2 support to the command line tool +* Renamed some switches in the command line tool +* Added additional configuration capabilities # 0.1.3 -* added support for manual overrides of the discovery URI -* added support for manual overrides of the API base -* added support for xoauth_requestor_id +* Added support for manual overrides of the discovery URI +* Added support for manual overrides of the API base +* Added support for xoauth_requestor_id # 0.1.2 -* added support for two-legged OAuth -* moved some development dependencies into runtime +* Added support for two-legged OAuth +* Moved some development dependencies into runtime # 0.1.1 -* substantial improvements to the command line interface +* Substantial improvements to the command line interface # 0.1.0 -* initial release +* Initial release diff --git a/README.md b/README.md index 85e796cab..8b445651c 100644 --- a/README.md +++ b/README.md @@ -46,14 +46,13 @@ APIs. client.authorization.fetch_token_credential!(:verifier => '12345') # Discover available methods - method_names = client.discovered_api('buzz').to_h.keys + method_names = client.discovered_api('plus').to_h.keys # Make an API call - response = client.execute( - 'chili.activities.list', - {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'} + result = client.execute( + 'plus.activities.list', + {'collection' => 'public', 'userId' => 'me'} ) - status, headers, body = response # Install diff --git a/bin/google-api b/bin/google-api index c80479e09..c1d61ae3a 100755 --- a/bin/google-api +++ b/bin/google-api @@ -10,7 +10,11 @@ OAUTH_SERVER_PORT = 12736 require 'rubygems' require 'optparse' -require 'httpadapter' + +gem 'faraday', '~> 0.7.0' +require 'faraday' +require 'faraday/utils' + require 'webrick' require 'google/api_client/version' require 'google/api_client' @@ -183,6 +187,7 @@ HTML end def client + gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' require 'yaml' require 'irb' @@ -276,6 +281,7 @@ HTML ] def oauth_1_login + gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' require 'launchy' require 'yaml' @@ -343,6 +349,7 @@ HTML end def oauth_2_login + gem 'signet', '~> 0.3.0' require 'signet/oauth_2/client' require 'launchy' require 'yaml' @@ -467,8 +474,7 @@ HTML request = [method, uri.to_str, headers, [request_body]] request = client.generate_authenticated_request(:request => request) response = client.transmit(request) - status, headers, body = response - puts body + puts response.body exit(0) else # Make request with URI generated from template and parameters @@ -502,8 +508,7 @@ HTML :merged_body => request_body, :headers => headers ) - status, headers, body = result.response - puts body + puts result.response.body exit(0) rescue ArgumentError => e puts e.message diff --git a/google-api-client.gemspec b/google-api-client.gemspec index 05f04b6a3..a96520a35 100644 --- a/google-api-client.gemspec +++ b/google-api-client.gemspec @@ -1,32 +1,36 @@ # -*- encoding: utf-8 -*- Gem::Specification.new do |s| - s.name = "google-api-client" - s.version = "0.3.0" + s.name = %q{google-api-client} + s.version = "0.4.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Bob Aman"] - s.date = "2011-11-22" - s.description = "The Google API Ruby Client makes it trivial to discover and access supported\nAPIs.\n" - s.email = "bobaman@google.com" + s.date = %q{2012-01-27} + s.default_executable = %q{google-api} + s.description = %q{The Google API Ruby Client makes it trivial to discover and access supported +APIs. +} + s.email = %q{bobaman@google.com} s.executables = ["google-api"] s.extra_rdoc_files = ["README.md"] - s.files = ["lib/google", "lib/google/api_client", "lib/google/api_client/discovery", "lib/google/api_client/discovery/api.rb", "lib/google/api_client/discovery/method.rb", "lib/google/api_client/discovery/resource.rb", "lib/google/api_client/discovery/schema.rb", "lib/google/api_client/discovery.rb", "lib/google/api_client/environment.rb", "lib/google/api_client/errors.rb", "lib/google/api_client/parser.rb", "lib/google/api_client/parsers", "lib/google/api_client/parsers/json", "lib/google/api_client/parsers/json/error_parser.rb", "lib/google/api_client/parsers/json/pagination.rb", "lib/google/api_client/parsers/json_parser.rb", "lib/google/api_client/reference.rb", "lib/google/api_client/result.rb", "lib/google/api_client/version.rb", "lib/google/api_client.rb", "lib/google/inflection.rb", "spec/google", "spec/google/api_client", "spec/google/api_client/discovery_spec.rb", "spec/google/api_client/parsers", "spec/google/api_client/parsers/json_parser_spec.rb", "spec/google/api_client_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rdoc.rake", "tasks/spec.rake", "tasks/wiki.rake", "tasks/yard.rake", "CHANGELOG.md", "LICENSE", "Rakefile", "README.md", "bin/google-api"] - s.homepage = "http://code.google.com/p/google-api-ruby-client/" + s.files = ["lib/google", "lib/google/api_client", "lib/google/api_client/discovery", "lib/google/api_client/discovery/api.rb", "lib/google/api_client/discovery/method.rb", "lib/google/api_client/discovery/resource.rb", "lib/google/api_client/discovery/schema.rb", "lib/google/api_client/discovery.rb", "lib/google/api_client/environment.rb", "lib/google/api_client/errors.rb", "lib/google/api_client/reference.rb", "lib/google/api_client/result.rb", "lib/google/api_client/version.rb", "lib/google/api_client.rb", "lib/google/inflection.rb", "spec/google", "spec/google/api_client", "spec/google/api_client/discovery_spec.rb", "spec/google/api_client_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rdoc.rake", "tasks/spec.rake", "tasks/wiki.rake", "tasks/yard.rake", "CHANGELOG.md", "LICENSE", "Rakefile", "README.md", "bin/google-api"] + s.homepage = %q{http://code.google.com/p/google-api-ruby-client/} s.rdoc_options = ["--main", "README.md"] s.require_paths = ["lib"] - s.rubygems_version = "1.8.11" - s.summary = "Package Summary" + s.rubygems_version = %q{1.3.7} + s.summary = %q{Package Summary} if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, ["~> 0.2.2"]) - s.add_runtime_dependency(%q, ["~> 2.2.2"]) - s.add_runtime_dependency(%q, ["~> 1.0.1"]) + s.add_runtime_dependency(%q, ["~> 0.3.0"]) + s.add_runtime_dependency(%q, ["~> 2.2.3"]) s.add_runtime_dependency(%q, ["~> 0.2.0"]) - s.add_runtime_dependency(%q, [">= 1.4.6"]) + s.add_runtime_dependency(%q, ["~> 0.7.0"]) + s.add_runtime_dependency(%q, [">= 1.0.0"]) s.add_runtime_dependency(%q, [">= 0.9.15"]) s.add_runtime_dependency(%q, [">= 2.0.0"]) s.add_development_dependency(%q, [">= 1.2.0"]) @@ -35,11 +39,11 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, [">= 0.9.9"]) s.add_development_dependency(%q, [">= 1.1.2"]) else - s.add_dependency(%q, ["~> 0.2.2"]) - s.add_dependency(%q, ["~> 2.2.2"]) - s.add_dependency(%q, ["~> 1.0.1"]) + s.add_dependency(%q, ["~> 0.3.0"]) + s.add_dependency(%q, ["~> 2.2.3"]) s.add_dependency(%q, ["~> 0.2.0"]) - s.add_dependency(%q, [">= 1.4.6"]) + s.add_dependency(%q, ["~> 0.7.0"]) + s.add_dependency(%q, [">= 1.0.0"]) s.add_dependency(%q, [">= 0.9.15"]) s.add_dependency(%q, [">= 2.0.0"]) s.add_dependency(%q, [">= 1.2.0"]) @@ -49,11 +53,11 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 1.1.2"]) end else - s.add_dependency(%q, ["~> 0.2.2"]) - s.add_dependency(%q, ["~> 2.2.2"]) - s.add_dependency(%q, ["~> 1.0.1"]) + s.add_dependency(%q, ["~> 0.3.0"]) + s.add_dependency(%q, ["~> 2.2.3"]) s.add_dependency(%q, ["~> 0.2.0"]) - s.add_dependency(%q, [">= 1.4.6"]) + s.add_dependency(%q, ["~> 0.7.0"]) + s.add_dependency(%q, [">= 1.0.0"]) s.add_dependency(%q, [">= 0.9.15"]) s.add_dependency(%q, [">= 2.0.0"]) s.add_dependency(%q, [">= 1.2.0"]) diff --git a/lib/google/api_client.rb b/lib/google/api_client.rb index a1074020a..a6e2db7ae 100644 --- a/lib/google/api_client.rb +++ b/lib/google/api_client.rb @@ -13,7 +13,9 @@ # limitations under the License. -require 'httpadapter' +gem 'faraday', '~> 0.7.0' +require 'faraday' +require 'faraday/utils' require 'multi_json' require 'stringio' @@ -81,16 +83,6 @@ module Google self.authorization = options["authorization"] || :oauth_2 self.key = options["key"] self.user_ip = options["user_ip"] - # The HTTP adapter controls all of the HTTP traffic the client generates. - # By default, Net::HTTP is used, but adding support for other clients - # is trivial. - if options["http_adapter"] - self.http_adapter = options["http_adapter"] - else - require 'httpadapter/adapters/net_http' - # NOTE: Do not rely on this default value, as it may change - self.http_adapter = HTTPAdapter::NetHTTPAdapter.new - end @discovery_uris = {} @discovery_documents = {} @discovered_apis = {} @@ -111,6 +103,7 @@ module Google def authorization=(new_authorization) case new_authorization when :oauth_1, :oauth + gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' # NOTE: Do not rely on this default value, as it may change new_authorization = Signet::OAuth1::Client.new( @@ -124,6 +117,7 @@ module Google :client_credential_secret => 'anonymous' ) when :two_legged_oauth_1, :two_legged_oauth + gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' # NOTE: Do not rely on this default value, as it may change new_authorization = Signet::OAuth1::Client.new( @@ -132,6 +126,7 @@ module Google :two_legged => true ) when :oauth_2 + gem 'signet', '~> 0.3.0' require 'signet/oauth_2/client' # NOTE: Do not rely on this default value, as it may change new_authorization = Signet::OAuth2::Client.new( @@ -165,28 +160,6 @@ module Google # @return [String] The user's IP address. attr_accessor :user_ip - ## - # Returns the HTTP adapter used by the client. - # - # @return [HTTPAdapter] - # The HTTP adapter object. The object must include the - # HTTPAdapter module and conform to its interface. - attr_reader :http_adapter - - ## - # Returns the HTTP adapter used by the client. - # - # @return [HTTPAdapter] - # The HTTP adapter object. The object must include the - # HTTPAdapter module and conform to its interface. - def http_adapter=(new_http_adapter) - if new_http_adapter.kind_of?(HTTPAdapter) - @http_adapter = new_http_adapter - else - raise TypeError, "Expected HTTPAdapter, got #{new_http_adapter.class}." - end - end - ## # The API hostname used by the client. # @@ -216,8 +189,8 @@ module Google # Manually registers a URI as a discovery document for a specific version # of an API. # - # @param [String, Symbol] api The service name. - # @param [String] version The desired version of the service. + # @param [String, Symbol] api The API name. + # @param [String] version The desired version of the API. # @param [Addressable::URI] uri The URI of the discovery document. def register_discovery_uri(api, version, uri) api = api.to_s @@ -228,8 +201,8 @@ module Google ## # Returns the URI for the discovery document. # - # @param [String, Symbol] api The service name. - # @param [String] version The desired version of the service. + # @param [String, Symbol] api The API name. + # @param [String] version The desired version of the API. # @return [Addressable::URI] The URI of the discovery document. def discovery_uri(api, version=nil) api = api.to_s @@ -251,8 +224,8 @@ module Google # Manually registers a pre-loaded discovery document for a specific version # of an API. # - # @param [String, Symbol] api The service name. - # @param [String] version The desired version of the service. + # @param [String, Symbol] api The API name. + # @param [String] version The desired version of the API. # @param [String, StringIO] discovery_document # The contents of the discovery document. def register_discovery_document(api, version, discovery_document) @@ -278,31 +251,25 @@ module Google def directory_document return @directory_document ||= (begin request = self.generate_request( - :http_method => 'GET', + :http_method => :get, :uri => self.directory_uri, :authenticated => false ) - response = self.transmit(request) - status, headers, body = response - if status >= 200 && status < 300 - # TODO(bobaman) Better status code handling? - merged_body = body.inject(StringIO.new) do |accu, chunk| - accu.write(chunk) - accu + response = self.transmit(:request => request) + if response.status >= 200 && response.status < 300 + MultiJson.decode(response.body) + elsif response.status >= 400 + case response.status + when 400...500 + exception_type = ClientError + when 500...600 + exception_type = ServerError + else + exception_type = TransmissionError end - MultiJson.decode(merged_body.string) - elsif status >= 400 && status < 500 - _, request_uri, _, _ = request - raise ClientError, - "Could not retrieve discovery document at: #{request_uri}" - elsif status >= 500 && status < 600 - _, request_uri, _, _ = request - raise ServerError, - "Could not retrieve discovery document at: #{request_uri}" - elsif status > 600 - _, request_uri, _, _ = request - raise TransmissionError, - "Could not retrieve discovery document at: #{request_uri}" + url = request.to_env(Faraday.default_connection)[:url] + raise exception_type, + "Could not retrieve directory document at: #{url}" end end) end @@ -310,39 +277,33 @@ module Google ## # Returns the parsed discovery document. # - # @param [String, Symbol] api The service name. - # @param [String] version The desired version of the service. + # @param [String, Symbol] api The API name. + # @param [String] version The desired version of the API. # @return [Hash] The parsed JSON from the discovery document. def discovery_document(api, version=nil) api = api.to_s version = version || 'v1' return @discovery_documents["#{api}:#{version}"] ||= (begin request = self.generate_request( - :http_method => 'GET', + :http_method => :get, :uri => self.discovery_uri(api, version), :authenticated => false ) - response = self.transmit(request) - status, headers, body = response - if status >= 200 && status < 300 - # TODO(bobaman) Better status code handling? - merged_body = body.inject(StringIO.new) do |accu, chunk| - accu.write(chunk) - accu + response = self.transmit(:request => request) + if response.status >= 200 && response.status < 300 + MultiJson.decode(response.body) + elsif response.status >= 400 + case response.status + when 400...500 + exception_type = ClientError + when 500...600 + exception_type = ServerError + else + exception_type = TransmissionError end - MultiJson.decode(merged_body.string) - elsif status >= 400 && status < 500 - _, request_uri, _, _ = request - raise ClientError, - "Could not retrieve discovery document at: #{request_uri}" - elsif status >= 500 && status < 600 - _, request_uri, _, _ = request - raise ServerError, - "Could not retrieve discovery document at: #{request_uri}" - elsif status > 600 - _, request_uri, _, _ = request - raise TransmissionError, - "Could not retrieve discovery document at: #{request_uri}" + url = request.to_env(Faraday.default_connection)[:url] + raise exception_type, + "Could not retrieve discovery document at: #{url}" end end) end @@ -370,8 +331,8 @@ module Google ## # Returns the service object for a given service name and service version. # - # @param [String, Symbol] api The service name. - # @param [String] version The desired version of the service. + # @param [String, Symbol] api The API name. + # @param [String] version The desired version of the API. # # @return [Google::APIClient::API] The service object. def discovered_api(api, version=nil) @@ -399,7 +360,8 @@ module Google # Returns the method object for a given RPC name and service version. # # @param [String, Symbol] rpc_name The RPC name of the desired method. - # @param [String] version The desired version of the service. + # @param [String, Symbol] rpc_name The API the method is within. + # @param [String] version The desired version of the API. # # @return [Google::APIClient::Method] The method object. def discovered_method(rpc_name, api, version=nil) @@ -434,7 +396,6 @@ module Google "Expected String or Symbol, got #{api.class}." end api = api.to_s - # TODO(bobaman): Update to use directory API. return self.discovered_apis.detect do |a| a.name == api && a.preferred == true end @@ -443,35 +404,29 @@ module Google ## # Generates a request. # - # @param [Google::APIClient::Method, String] api_method + # @option options [Google::APIClient::Method, String] :api_method # The method object or the RPC name of the method being executed. - # @param [Hash, Array] parameters + # @option options [Hash, Array] :parameters # The parameters to send to the method. - # @param [String] body The body of the request. - # @param [Hash, Array] headers The HTTP headers for the request. - # @param [Hash] options - # The configuration parameters for the request. - # - :version — - # The service version. Only used if api_method is a - # String. Defaults to 'v1'. - # - :authorization — - # The authorization mechanism for the response. Used only if - # :authenticated is true. - # - :authenticated — - # true if the request must be signed or otherwise - # authenticated, false - # otherwise. Defaults to true if an authorization - # mechanism has been set, false otherwise. + # @option options [Hash, Array] :headers The HTTP headers for the request. + # @option options [String] :body The body of the request. + # @option options [String] :version ("v1") + # The service version. Only used if `api_method` is a `String`. + # @option options [#generate_authenticated_request] :authorization + # The authorization mechanism for the response. Used only if + # `:authenticated` is `true`. + # @option options [TrueClass, FalseClass] :authenticated (true) + # `true` if the request must be signed or somehow + # authenticated, `false` otherwise. # - # @return [Array] The generated request. + # @return [Faraday::Request] The generated request. # # @example # request = client.generate_request( - # :api_method => 'chili.activities.list', + # :api_method => 'plus.activities.list', # :parameters => - # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'} + # {'collection' => 'public', 'userId' => 'me'} # ) - # method, uri, headers, body = request def generate_request(options={}) # Note: The merge method on a Hash object will coerce an API Reference # object into a Hash and merge with the default options. @@ -479,7 +434,8 @@ module Google :version => 'v1', :authorization => self.authorization, :key => self.key, - :user_ip => self.user_ip + :user_ip => self.user_ip, + :connection => Faraday.default_connection }.merge(options) # The Reference object is going to need this to do method ID lookups. options[:client] = self @@ -493,7 +449,10 @@ module Google reference = Google::APIClient::Reference.new(options) request = reference.to_request if options[:authenticated] - request = self.generate_authenticated_request(:request => request) + request = self.generate_authenticated_request( + :request => request, + :connection => options[:connection] + ) end return request end @@ -501,9 +460,9 @@ module Google ## # Signs a request using the current authorization mechanism. # - # @param [Hash] options The options to pass through. + # @param [Hash] options a customizable set of options # - # @return [Array] The signed or otherwise authenticated request. + # @return [Faraday::Request] The signed or otherwise authenticated request. def generate_authenticated_request(options={}) return authorization.generate_authenticated_request(options) end @@ -511,14 +470,59 @@ module Google ## # Transmits the request using the current HTTP adapter. # - # @param [Array] request The request to transmit. - # @param [#transmit] adapter The HTTP adapter. + # @option options [Array, Faraday::Request] :request + # The HTTP request to transmit. + # @option options [String, Symbol] :method + # The method for the HTTP request. + # @option options [String, Addressable::URI] :uri + # The URI for the HTTP request. + # @option options [Array, Hash] :headers + # The headers for the HTTP request. + # @option options [String] :body + # The body for the HTTP request. + # @option options [Faraday::Connection] :connection + # The HTTP connection to use. # - # @return [Array] The response from the server. - def transmit(request, adapter=self.http_adapter) + # @return [Faraday::Response] The response from the server. + def transmit(options={}) + options[:connection] ||= Faraday.default_connection + if options[:request] + if options[:request].kind_of?(Array) + method, uri, headers, body = options[:request] + elsif options[:request].kind_of?(Faraday::Request) + unless options[:connection] + raise ArgumentError, + "Faraday::Request used, requires a connection to be provided." + end + method = options[:request].method.to_s.downcase.to_sym + uri = options[:connection].build_url( + options[:request].path, options[:request].params + ) + headers = options[:request].headers || {} + body = options[:request].body || '' + end + else + method = options[:method] || :get + uri = options[:uri] + headers = options[:headers] || [] + body = options[:body] || '' + end + headers = headers.to_a if headers.kind_of?(Hash) + request_components = { + :method => method, + :uri => uri, + :headers => headers, + :body => body + } + # Verify that we have all pieces required to transmit an HTTP request + request_components.each do |(key, value)| + unless value + raise ArgumentError, "Missing :#{key} parameter." + end + end + if self.user_agent != nil # If there's no User-Agent header, set one. - method, uri, headers, body = request unless headers.kind_of?(Enumerable) # We need to use some Enumerable methods, relying on the presence of # the #each method. @@ -535,7 +539,15 @@ module Google "Expected User-Agent to be String, got #{self.user_agent.class}" end end - adapter.transmit([method, uri, headers, body]) + + request = Faraday::Request.create(method.to_s.downcase.to_sym) do |req| + req.url(Addressable::URI.parse(uri)) + req.headers = Faraday::Utils::Headers.new(headers) + req.body = body + end + request_env = request.to_env(options[:connection]) + response = options[:connection].app.call(request_env) + return response end ## @@ -547,29 +559,24 @@ module Google # The parameters to send to the method. # @param [String] body The body of the request. # @param [Hash, Array] headers The HTTP headers for the request. - # @param [Hash] options - # The configuration parameters for the request. - # - :version — - # The service version. Only used if api_method is a - # String. Defaults to 'v1'. - # - :adapter — - # The HTTP adapter. - # - :authorization — - # The authorization mechanism for the response. Used only if - # :authenticated is true. - # - :authenticated — - # true if the request must be signed or otherwise - # authenticated, false - # otherwise. Defaults to true. + # @option options [String] :version ("v1") + # The service version. Only used if `api_method` is a `String`. + # @option options [#generate_authenticated_request] :authorization + # The authorization mechanism for the response. Used only if + # `:authenticated` is `true`. + # @option options [TrueClass, FalseClass] :authenticated (true) + # `true` if the request must be signed or somehow + # authenticated, `false` otherwise. # - # @return [Array] The response from the API. + # @return [Google::APIClient::Result] The result from the API. # # @example - # request = client.generate_request( - # :api_method => 'chili.activities.list', - # :parameters => - # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'} + # result = client.execute( + # :api_method => 'plus.activities.list', + # :parameters => {'collection' => 'public', 'userId' => 'me'} # ) + # + # @see Google::APIClient#generate_request def execute(*params) # This block of code allows us to accept multiple parameter passing # styles, and maintaining some backwards compatibility. @@ -582,15 +589,15 @@ module Google end options[:api_method] = params.shift if params.size > 0 options[:parameters] = params.shift if params.size > 0 - options[:merged_body] = params.shift if params.size > 0 + options[:body] = params.shift if params.size > 0 options[:headers] = params.shift if params.size > 0 options[:client] = self reference = Google::APIClient::Reference.new(options) request = self.generate_request(reference) response = self.transmit( - request, - options[:adapter] || self.http_adapter + :request => request, + :connection => options[:connection] ) return Google::APIClient::Result.new(reference, request, response) end @@ -602,7 +609,6 @@ module Google # @see Google::APIClient#execute def execute!(*params) result = self.execute(*params) - status, _, _ = result.response if result.data.respond_to?(:error) && result.data.error.respond_to?(:message) # You're going to get a terrible error message if the response isn't @@ -611,15 +617,19 @@ module Google elsif result.data['error'] && result.data['error']['message'] error_message = result.data['error']['message'] end - if status >= 400 && status < 500 - raise ClientError, - error_message || "A client error has occurred." - elsif status >= 500 && status < 600 - raise ServerError, - error_message || "A server error has occurred." - elsif status > 600 - raise TransmissionError, - error_message || "A transmission error has occurred." + if result.response.status >= 400 + case result.response.status + when 400...500 + exception_type = ClientError + error_message ||= "A client error has occurred." + when 500...600 + exception_type = ServerError + error_message ||= "A server error has occurred." + else + exception_type = TransmissionError + error_message ||= "A transmission error has occurred." + end + raise exception_type, error_message end return result end diff --git a/lib/google/api_client/discovery/method.rb b/lib/google/api_client/discovery/method.rb index 8f27d9a5c..a1ec1b455 100644 --- a/lib/google/api_client/discovery/method.rb +++ b/lib/google/api_client/discovery/method.rb @@ -203,7 +203,11 @@ module Google method = self.http_method uri = self.generate_uri(parameters) headers = headers.to_a if headers.kind_of?(Hash) - return [method, uri.to_str, headers, [body]] + return Faraday::Request.create(method.to_s.downcase.to_sym) do |req| + req.url(Addressable::URI.parse(uri)) + req.headers = Faraday::Utils::Headers.new(headers) + req.body = body + end end ## diff --git a/lib/google/api_client/parser.rb b/lib/google/api_client/parser.rb deleted file mode 100644 index 84b5918d0..000000000 --- a/lib/google/api_client/parser.rb +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require 'multi_json' - - -module Google - class APIClient - module Parser - def content_type(content_type) - @@content_type_mapping ||= {} - @@content_type_mapping[content_type] = self - end - - def self.match_content_type(content_type) - # TODO(bobaman): Do this more efficiently. - mime_type_regexp = /^([^\/]+)(?:\/([^+]+\+)?([^;]+))?(?:;.*)?$/ - if @@content_type_mapping[content_type] - # Exact match - return @@content_type_mapping[content_type] - else - media_type, extension, sub_type = - content_type.scan(mime_type_regexp)[0] - for pattern, parser in @@content_type_mapping - # We want to match on subtype first - pattern_media_type, pattern_extension, pattern_sub_type = - pattern.scan(mime_type_regexp)[0] - next if pattern_extension != nil - if media_type == pattern_media_type && sub_type == pattern_sub_type - return parser - end - end - for pattern, parser in @@content_type_mapping - # We failed to match on the subtype - # Try to match only on the media type - pattern_media_type, pattern_extension, pattern_sub_type = - pattern.scan(mime_type_regexp)[0] - next if pattern_extension != nil || pattern_sub_type != nil - if media_type == pattern_media_type - return parser - end - end - end - return nil - end - end - end -end diff --git a/lib/google/api_client/parsers/json/error_parser.rb b/lib/google/api_client/parsers/json/error_parser.rb deleted file mode 100644 index 3a8a9256f..000000000 --- a/lib/google/api_client/parsers/json/error_parser.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require 'google/api_client/parsers/json_parser' - - -module Google - class APIClient - module JSON - ## - # A module which provides a parser for error responses. - class ErrorParser - include Google::APIClient::JSONParser - - matches_fields 'error' - - def error - return self['error']['message'] - end - end - end - end -end diff --git a/lib/google/api_client/parsers/json/pagination.rb b/lib/google/api_client/parsers/json/pagination.rb deleted file mode 100644 index 69581e2d0..000000000 --- a/lib/google/api_client/parsers/json/pagination.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require 'google/api_client/parsers/json_parser' - - -module Google - class APIClient - module JSON - ## - # A module which provides a paginated parser. - module Pagination - def self.included(parser) - parser.class_eval do - include Google::APIClient::JSONParser - end - end - - def next_page_token - return self["nextPageToken"] - end - - def prev_page_token - return self["prevPageToken"] - end - end - end - end -end diff --git a/lib/google/api_client/parsers/json_parser.rb b/lib/google/api_client/parsers/json_parser.rb deleted file mode 100644 index 56b6c7663..000000000 --- a/lib/google/api_client/parsers/json_parser.rb +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require 'multi_json' -require 'google/api_client/parser' - - -module Google - class APIClient - ## - # Provides a module which all other parsers should include. - module JSONParser - extend Parser - content_type 'application/json' - - module Matcher - def conditions - @conditions ||= [] - end - - def matches_kind(kind) - self.matches_field_value(:kind, kind) - end - - def matches_fields(fields) - self.conditions << [:fields, fields] - end - - def matches_field_value(field, value) - self.conditions << [:field_value, field, value] - end - end - - def self.parsers - @parsers ||= [] - end - - ## - # This method ensures that all parsers auto-register themselves. - def self.included(parser) - self.parsers << parser - parser.extend(Matcher) - end - - def initialize(data) - @data = data.kind_of?(Hash) ? data : MultiJson.decode(data) - end - - def [](key) - return self.json[key] - end - - def json - if @data - data = @data - elsif self.respond_to?(:data) - data = self.data - else - raise TypeError, "Parser did not provide access to raw data." - end - return data - end - - ## - # Matches a parser to the data. - def self.match(data) - for parser in self.parsers - conditions_met = true - for condition in (parser.conditions.sort_by { |c| c.size }).reverse - condition_type, *params = condition - case condition_type - when :fields - for field in params - if !data.has_key?(field) - conditions_met = false - break - end - end - when :field_values - field, value = params - if data[field] != value - conditions_met = false - break - end - else - raise ArgumentError, "Unknown condition type: #{condition_type}" - end - break if !conditions_met - end - if conditions_met - return parser - end - end - return nil - end - - def self.parse(json) - data = json.kind_of?(Hash) ? json : MultiJson.decode(json) - parser = self.match(data) - if parser - return parser.new(data) - else - return data - end - end - end - end -end diff --git a/lib/google/api_client/reference.rb b/lib/google/api_client/reference.rb index 936ae60d4..4c67bca1e 100644 --- a/lib/google/api_client/reference.rb +++ b/lib/google/api_client/reference.rb @@ -13,9 +13,12 @@ # limitations under the License. -require 'stringio' +gem 'faraday', '~> 0.7.0' +require 'faraday' +require 'faraday/utils' require 'multi_json' require 'addressable/uri' +require 'stringio' require 'google/api_client/discovery' @@ -29,6 +32,7 @@ module Google @client = options[:client] @version = options[:version] || 'v1' + self.connection = options[:connection] || Faraday.default_connection self.api_method = options[:api_method] self.parameters = options[:parameters] || {} # These parameters are handled differently because they're not @@ -38,8 +42,6 @@ module Google self.headers = options[:headers] || [] if options[:body] self.body = options[:body] - elsif options[:merged_body] - self.merged_body = options[:merged_body] elsif options[:body_object] if options[:body_object].respond_to?(:to_json) serialized_body = options[:body_object].to_json @@ -50,9 +52,9 @@ module Google 'Could not convert body object to JSON.' + 'Must respond to :to_json or :to_hash.' end - self.merged_body = serialized_body + self.body = serialized_body else - self.merged_body = '' + self.body = '' end unless self.api_method self.http_method = options[:http_method] || 'GET' @@ -64,6 +66,19 @@ module Google end end + def connection + return @connection + end + + def connection=(new_connection) + if new_connection.kind_of?(Faraday::Connection) + @connection = new_connection + else + raise TypeError, + "Expected Faraday::Connection, got #{new_connection.class}." + end + end + def api_method return @api_method end @@ -115,32 +130,18 @@ module Google end def body=(new_body) - if new_body.respond_to?(:each) - @body = new_body + if new_body.respond_to?(:to_str) + @body = new_body.to_str + elsif new_body.respond_to?(:inject) + @body = (new_body.inject(StringIO.new) do |accu, chunk| + accu.write(chunk) + accu + end).string else - raise TypeError, "Expected body to respond to :each." + raise TypeError, "Expected body to be String or Enumerable chunks." end end - def merged_body - return (self.body.inject(StringIO.new) do |accu, chunk| - accu.write(chunk) - accu - end).string - end - - def merged_body=(new_merged_body) - if new_merged_body.respond_to?(:string) - new_merged_body = new_merged_body.string - elsif new_merged_body.respond_to?(:to_str) - new_merged_body = new_merged_body.to_str - else - raise TypeError, - "Expected String or StringIO, got #{new_merged_body.class}." - end - self.body = [new_merged_body] - end - def headers return @headers ||= [] end @@ -179,10 +180,16 @@ module Google def to_request if self.api_method return self.api_method.generate_request( - self.parameters, self.merged_body, self.headers + self.parameters, self.body, self.headers ) else - return [self.http_method, self.uri, self.headers, self.body] + return Faraday::Request.create( + self.http_method.to_s.downcase.to_sym + ) do |req| + req.url(Addressable::URI.parse(self.uri)) + req.headers = Faraday::Utils::Headers.new(self.headers) + req.body = self.body + end end end @@ -197,6 +204,7 @@ module Google end options[:headers] = self.headers options[:body] = self.body + options[:connection] = self.connection return options end end diff --git a/lib/google/api_client/result.rb b/lib/google/api_client/result.rb index 65bac1575..05fa3c7b6 100644 --- a/lib/google/api_client/result.rb +++ b/lib/google/api_client/result.rb @@ -31,21 +31,15 @@ module Google attr_reader :response def status - return @response[0] + return @response.status end def headers - return @response[1] + return @response.headers end def body - return @body ||= (begin - response_body = @response[2] - merged_body = (response_body.inject(StringIO.new) do |accu, chunk| - accu.write(chunk) - accu - end).string - end) + return @response.body end def data diff --git a/lib/google/api_client/version.rb b/lib/google/api_client/version.rb index 7b6fae529..ea35936e0 100644 --- a/lib/google/api_client/version.rb +++ b/lib/google/api_client/version.rb @@ -21,7 +21,7 @@ if !defined?(::Google::APIClient::VERSION) class APIClient module VERSION MAJOR = 0 - MINOR = 3 + MINOR = 4 TINY = 0 STRING = [MAJOR, MINOR, TINY].join('.') diff --git a/spec/google/api_client/discovery_spec.rb b/spec/google/api_client/discovery_spec.rb index 1d5cc22d0..616248725 100644 --- a/spec/google/api_client/discovery_spec.rb +++ b/spec/google/api_client/discovery_spec.rb @@ -14,9 +14,13 @@ require 'spec_helper' +gem 'faraday', '~> 0.7.0' +require 'faraday' +require 'faraday/utils' require 'multi_json' + +gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' -require 'httpadapter/adapters/net_http' require 'google/api_client' require 'google/api_client/version' @@ -84,8 +88,7 @@ describe Google::APIClient do :uri => @client.discovery_uri('prediction', 'v1.2'), :authenticated => false ) - http_method, uri, headers, body = request - uri.should === ( + request.to_env(Faraday.default_connection)[:url].should === ( 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' + '?userIp=127.0.0.1' ) @@ -98,8 +101,7 @@ describe Google::APIClient do :uri => @client.discovery_uri('prediction', 'v1.2'), :authenticated => false ) - http_method, uri, headers, body = request - uri.should === ( + request.to_env(Faraday.default_connection)[:url].should === ( 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' + '?key=qwerty' ) @@ -113,11 +115,10 @@ describe Google::APIClient do :uri => @client.discovery_uri('prediction', 'v1.2'), :authenticated => false ) - http_method, uri, headers, body = request - uri.should === ( - 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' + - '?key=qwerty&userIp=127.0.0.1' - ) + request.to_env(Faraday.default_connection)[:url].query_values.should == { + 'key' => 'qwerty', + 'userIp' => '127.0.0.1' + } end it 'should correctly generate API objects' do @@ -167,30 +168,29 @@ describe Google::APIClient do :api_method => @prediction.training.insert, :parameters => {'data' => '12345', } ) - method, uri, headers, body = request - method.should == 'POST' - uri.should == + request.method.should == :post + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/prediction/v1.2/training?data=12345' - (headers.inject({}) { |h,(k,v)| h[k]=v; h }).should == {} - body.should respond_to(:each) + request.headers.should be_empty + request.body.should == '' end + it 'should generate valid requests when repeated parameters are passed' do request = @client.generate_request( :api_method => @prediction.training.insert, :parameters => [['data', '1'],['data','2']] ) - method, uri, headers, body = request - method.should == 'POST' - uri.should == + request.method.should == :post + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2' end + it 'should generate requests against the correct URIs' do request = @client.generate_request( :api_method => @prediction.training.insert, :parameters => {'data' => '12345'} ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/prediction/v1.2/training?data=12345' end @@ -199,8 +199,7 @@ describe Google::APIClient do :api_method => @prediction.training.insert, :parameters => {'data' => '12345'} ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/prediction/v1.2/training?data=12345' end @@ -212,8 +211,7 @@ describe Google::APIClient do :api_method => prediction.training.insert, :parameters => {'data' => '123'} ) - method, uri, headers, body = request - uri.should == ( + request.to_env(Faraday.default_connection)[:url].should === ( 'https://testing-domain.googleapis.com/' + 'prediction/v1.2/training?data=123' ) @@ -227,10 +225,8 @@ describe Google::APIClient do :api_method => @prediction.training.insert, :parameters => {'data' => '12345'} ) - method, uri, headers, body = request - headers = headers.inject({}) { |h,(k,v)| h[k]=v; h } - headers.keys.should include('Authorization') - headers['Authorization'].should =~ /^OAuth/ + request.headers.should have_key('Authorization') + request.headers['Authorization'].should =~ /^OAuth/ end it 'should generate OAuth 2 requests' do @@ -240,10 +236,8 @@ describe Google::APIClient do :api_method => @prediction.training.insert, :parameters => {'data' => '12345'} ) - method, uri, headers, body = request - headers = headers.inject({}) { |h,(k,v)| h[k]=v; h } - headers.keys.should include('Authorization') - headers['Authorization'].should =~ /^OAuth/ + request.headers.should have_key('Authorization') + request.headers['Authorization'].should =~ /^Bearer/ end it 'should not be able to execute improperly authorized requests' do @@ -254,8 +248,7 @@ describe Google::APIClient do @prediction.training.insert, {'data' => '12345'} ) - status, headers, body = result.response - status.should == 401 + result.response.status.should == 401 end it 'should not be able to execute improperly authorized requests' do @@ -265,8 +258,7 @@ describe Google::APIClient do @prediction.training.insert, {'data' => '12345'} ) - status, headers, body = result.response - status.should == 401 + result.response.status.should == 401 end it 'should not be able to execute improperly authorized requests' do @@ -301,8 +293,7 @@ describe Google::APIClient do MultiJson.encode({"id" => "bucket/object"}), {'Content-Type' => 'application/json'} ) - method, uri, headers, body = result.request - Hash[headers]['Content-Type'].should == 'application/json' + result.request.headers['Content-Type'].should == 'application/json' end end @@ -343,8 +334,7 @@ describe Google::APIClient do }, :authenticated => false ) - method, uri, headers, body = request - uri.should == ( + request.to_env(Faraday.default_connection)[:url].should === ( 'https://www.googleapis.com/plus/v1/' + 'people/107807692475771887386/activities/public' ) @@ -404,8 +394,7 @@ describe Google::APIClient do :api_method => 'latitude.currentLocation.get', :authenticated => false ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/latitude/v1/currentLocation' end @@ -414,8 +403,7 @@ describe Google::APIClient do :api_method => @latitude.current_location.get, :authenticated => false ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/latitude/v1/currentLocation' end @@ -424,8 +412,7 @@ describe Google::APIClient do :api_method => 'latitude.currentLocation.get', :authenticated => false ) - status, headers, body = result.response - status.should == 401 + result.response.status.should == 401 end end @@ -460,8 +447,7 @@ describe Google::APIClient do :api_method => 'moderator.profiles.get', :authenticated => false ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/moderator/v1/profiles/@me' end @@ -470,8 +456,7 @@ describe Google::APIClient do :api_method => @moderator.profiles.get, :authenticated => false ) - method, uri, headers, body = request - uri.should == + request.to_env(Faraday.default_connection)[:url].should === 'https://www.googleapis.com/moderator/v1/profiles/@me' end @@ -483,8 +468,7 @@ describe Google::APIClient do [], {:authenticated => false} ) - status, headers, body = result.response - status.should == 401 + result.response.status.should == 401 end end end diff --git a/spec/google/api_client/parsers/json_parser_spec.rb b/spec/google/api_client/parsers/json_parser_spec.rb deleted file mode 100644 index e04d71cdb..000000000 --- a/spec/google/api_client/parsers/json_parser_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' - -require 'multi_json' -require 'google/api_client/parsers/json_parser' -require 'google/api_client/parsers/json/error_parser' -require 'google/api_client/parsers/json/pagination' - -describe Google::APIClient::JSONParser, 'with error data' do - before do - @data = { - 'error' => { - 'code' => 401, - 'message' => 'Token invalid - Invalid AuthSub token.', - 'errors' => [ - { - 'location' => 'Authorization', - 'domain' => 'global', - 'locationType' => 'header', - 'reason' => 'authError', - 'message' => 'Token invalid - Invalid AuthSub token.' - } - ] - } - } - end - - it 'should correctly match as an error' do - parser = Google::APIClient::JSONParser.match(@data) - parser.should == Google::APIClient::JSON::ErrorParser - end - - it 'should be automatically handled as an error when parsed' do - data = Google::APIClient::JSONParser.parse(@data) - data.should be_kind_of(Google::APIClient::JSON::ErrorParser) - end - - it 'should correctly expose error message' do - data = Google::APIClient::JSONParser.parse(@data) - data.error.should == 'Token invalid - Invalid AuthSub token.' - end -end diff --git a/spec/google/api_client_spec.rb b/spec/google/api_client_spec.rb index 78b36ba96..ee25dab9d 100644 --- a/spec/google/api_client_spec.rb +++ b/spec/google/api_client_spec.rb @@ -14,9 +14,12 @@ require 'spec_helper' +gem 'faraday', '~> 0.7.0' +require 'faraday' +require 'faraday/utils' + +gem 'signet', '~> 0.3.0' require 'signet/oauth_1/client' -require 'httpadapter/adapters/net_http' -require 'httpadapter/adapters/mock' require 'google/api_client' require 'google/api_client/version' @@ -44,16 +47,22 @@ shared_examples_for 'configurable user agent' do it 'should transmit a User-Agent header when sending requests' do @client.user_agent = 'Custom User Agent/1.2.3' - request = ['GET', 'http://www.google.com/', [], []] - adapter = HTTPAdapter::MockAdapter.create do |request_ary, connection| - method, uri, headers, body = request_ary - headers.should be_any { |k, v| k.downcase == 'user-agent' } - headers.each do |k, v| - v.should == @client.user_agent if k.downcase == 'user-agent' - end - [200, [], ['']] + request = Faraday::Request.new(:get) do |req| + req.url('http://www.google.com/') end - @client.transmit(request, adapter) + stubs = Faraday::Adapter::Test::Stubs.new do |stub| + stub.get('/') do |env| + headers = env[:request_headers] + headers.should have_key('User-Agent') + headers['User-Agent'].should == @client.user_agent + [200, {}, ['']] + end + end + connection = Faraday.new(:url => 'https://www.google.com') do |builder| + builder.adapter(:test, stubs) + end + @client.transmit(:request => request, :connection => connection) + stubs.verify_stubbed_calls end end diff --git a/tasks/gem.rake b/tasks/gem.rake index 0c47cb95d..4fcf82982 100644 --- a/tasks/gem.rake +++ b/tasks/gem.rake @@ -24,10 +24,10 @@ namespace :gem do s.rdoc_options.concat ['--main', 'README.md'] # Dependencies used in the main library - s.add_runtime_dependency('signet', '~> 0.2.2') - s.add_runtime_dependency('addressable', '~> 2.2.2') - s.add_runtime_dependency('httpadapter', '~> 1.0.1') + s.add_runtime_dependency('signet', '~> 0.3.0') + s.add_runtime_dependency('addressable', '~> 2.2.3') s.add_runtime_dependency('autoparse', '~> 0.2.0') + s.add_runtime_dependency('faraday', '~> 0.7.0') s.add_runtime_dependency('multi_json', '>= 1.0.0') s.add_runtime_dependency('extlib', '>= 0.9.15') diff --git a/tasks/wiki.rake b/tasks/wiki.rake index 8dd998a5b..4e7f2aca8 100644 --- a/tasks/wiki.rake +++ b/tasks/wiki.rake @@ -1,9 +1,3 @@ -$LOAD_PATH.unshift( - File.expand_path(File.join(File.dirname(__FILE__), '../yard/lib')) -) -$LOAD_PATH.unshift(File.expand_path('.')) -$LOAD_PATH.uniq! - require 'google/api_client' require 'rake' require 'rake/clean' @@ -54,6 +48,12 @@ WIKI end begin + $LOAD_PATH.unshift( + File.expand_path(File.join(File.dirname(__FILE__), '../yard/lib')) + ) + $LOAD_PATH.unshift(File.expand_path('.')) + $LOAD_PATH.uniq! + require 'yard' require 'yard/rake/wikidoc_task' @@ -63,6 +63,7 @@ begin yardoc.name = 'reference' yardoc.options = [ '--verbose', + '--markup', 'markdown', '-e', 'yard/lib/yard-google-code.rb', '-p', 'yard/templates', '-f', 'wiki', diff --git a/tasks/yard.rake b/tasks/yard.rake index 57cd3d8bf..64a28c6ed 100644 --- a/tasks/yard.rake +++ b/tasks/yard.rake @@ -12,7 +12,7 @@ begin desc 'Generate Yardoc documentation' YARD::Rake::YardocTask.new do |yardoc| yardoc.name = 'yard' - yardoc.options = ['--verbose'] + yardoc.options = ['--verbose', '--markup', 'markdown'] yardoc.files = [ 'lib/**/*.rb', 'ext/**/*.c', '-', 'README.md', 'CHANGELOG.md', 'LICENSE'