aitch 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +26 -0
  3. data/.travis.yml +2 -5
  4. data/Gemfile +2 -2
  5. data/README.md +11 -0
  6. data/Rakefile +5 -1
  7. data/aitch.gemspec +11 -7
  8. data/lib/aitch.rb +12 -13
  9. data/lib/aitch/configuration.rb +1 -0
  10. data/lib/aitch/dsl.rb +4 -3
  11. data/lib/aitch/engines/json.rb +2 -0
  12. data/lib/aitch/errors.rb +1 -0
  13. data/lib/aitch/ext/to_query.rb +7 -5
  14. data/lib/aitch/location.rb +4 -3
  15. data/lib/aitch/namespace.rb +35 -9
  16. data/lib/aitch/redirect.rb +1 -0
  17. data/lib/aitch/request.rb +30 -21
  18. data/lib/aitch/response.rb +8 -4
  19. data/lib/aitch/response/body.rb +1 -0
  20. data/lib/aitch/response/description.rb +3 -2
  21. data/lib/aitch/response/errors.rb +2 -1
  22. data/lib/aitch/response_parser.rb +8 -5
  23. data/lib/aitch/response_parser/default_parser.rb +2 -1
  24. data/lib/aitch/response_parser/html_parser.rb +1 -0
  25. data/lib/aitch/response_parser/json_parser.rb +1 -0
  26. data/lib/aitch/response_parser/xml_parser.rb +1 -0
  27. data/lib/aitch/uri.rb +6 -3
  28. data/lib/aitch/utils.rb +3 -1
  29. data/lib/aitch/version.rb +2 -1
  30. data/test/aitch/aitch_test.rb +1 -0
  31. data/test/aitch/configuration_test.rb +2 -1
  32. data/test/aitch/dsl_test.rb +1 -0
  33. data/test/aitch/execute_test.rb +1 -0
  34. data/test/aitch/namespace_test.rb +2 -1
  35. data/test/aitch/request/client_https_test.rb +1 -0
  36. data/test/aitch/request/follow_redirect_test.rb +4 -3
  37. data/test/aitch/request/json_request_test.rb +1 -0
  38. data/test/aitch/request/request_class_test.rb +3 -2
  39. data/test/aitch/request/status_code_validation_test.rb +3 -2
  40. data/test/aitch/request_test.rb +31 -6
  41. data/test/aitch/response/custom_response_parser_test.rb +1 -0
  42. data/test/aitch/response/errors_test.rb +1 -0
  43. data/test/aitch/response/html_response_test.rb +1 -0
  44. data/test/aitch/response/json_response_test.rb +2 -1
  45. data/test/aitch/response/raw_response_test.rb +1 -0
  46. data/test/aitch/response/status_3xx_test.rb +1 -0
  47. data/test/aitch/response/status_4xx_test.rb +1 -0
  48. data/test/aitch/response/status_5xx_test.rb +1 -0
  49. data/test/aitch/response/xml_response_test.rb +1 -0
  50. data/test/aitch/response_parser/html_parser_test.rb +1 -0
  51. data/test/aitch/response_parser/json_parser_test.rb +1 -0
  52. data/test/aitch/response_parser/xml_parser_test.rb +1 -1
  53. data/test/aitch/response_test.rb +1 -1
  54. data/test/aitch/uri_test.rb +2 -1
  55. data/test/aitch/utils/symbolize_keys_test.rb +1 -0
  56. data/test/aitch/utils/underscore_test.rb +1 -0
  57. data/test/support/helpers.rb +5 -4
  58. data/test/test_helper.rb +3 -2
  59. metadata +67 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 12767d163caa4e9cc79b97ff3f8e2cea1c48a494
4
- data.tar.gz: 38ef91d2cb1d478d890ee7215317e8b6205b2c47
2
+ SHA256:
3
+ metadata.gz: 79fcbcbeb7a0487eb6071a17cdfe2a4ffceed98d1c1358a7e5a6613d916a0256
4
+ data.tar.gz: a302171234f54b7b6607a5c8a8eda1c8b32c3b35658e65323ccd5a5cd6403ed3
5
5
  SHA512:
6
- metadata.gz: 5f61de59c13b8716f6deb85fdeb9b9aaa281afc98a9a27dac34c3dc8dd71f5a8390ac7d9c43e11ded32433b25e1f1a50e5ddef36d6588cb088c7ccd2f1233cf7
7
- data.tar.gz: dfb08e263ebca21387c417d52bcaabb2316bc15dfc29b64fd94401e8c47bee8496e811b7384e01c1812283b1350f71af24bc0398b946aee01983c30e173343e5
6
+ metadata.gz: f144ceb163b3a9cd1a91649b67bc5771fb5f73dcd021846147aa7b5583eeb4a13aa2d694cd7f468ca292b14e3226f09be8b0c9dd17292bfc74bc3792eabc2707
7
+ data.tar.gz: 15974c7b5905d82798affa69f3494d6ca43b32e4f7ee4b175b350994d9627a0df04af3aa626cec9424ea31ae23da626ae212f446b79c571acb6cf39afc317d81
@@ -0,0 +1,26 @@
1
+ ---
2
+ inherit_gem:
3
+ rubocop-fnando: .rubocop.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
7
+
8
+ Layout/LineLength:
9
+ Exclude:
10
+ - test/**/*.rb
11
+
12
+ Naming/AccessorMethodName:
13
+ Exclude:
14
+ - lib/aitch/request.rb
15
+
16
+ Metrics/ClassLength:
17
+ Enabled: false
18
+
19
+ Metrics/AbcSize:
20
+ Enabled: false
21
+
22
+ Metrics/MethodLength:
23
+ Enabled: false
24
+
25
+ Metrics/ParameterLists:
26
+ Enabled: false
@@ -1,3 +1,4 @@
1
+ ---
1
2
  language: ruby
2
3
  script: "bundle exec rake"
3
4
  before_install: gem install bundler
@@ -5,11 +6,7 @@ cache: bundler
5
6
  sudo: false
6
7
 
7
8
  rvm:
8
- - "2.3.0"
9
- - "2.2"
10
- - "2.1"
11
- - "2.0"
12
- - jruby-head
9
+ - "2.7"
13
10
 
14
11
  gemfile:
15
12
  - Gemfile
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
  gemspec
3
-
4
- gem "pry-meta", platforms: [:ruby_20, :ruby_21, :ruby_22, :ruby_23]
data/README.md CHANGED
@@ -83,6 +83,17 @@ response = Aitch.get do
83
83
  end
84
84
  ```
85
85
 
86
+ Finally, you can use keyword arguments:
87
+
88
+ ```ruby
89
+ Aitch.get(
90
+ url: "http://example.org",
91
+ params: {a: 1, b: 2},
92
+ headers: {Authorization: "Token token=abc"},
93
+ options: {follow_redirect: false}
94
+ )
95
+ ```
96
+
86
97
  ### Response
87
98
 
88
99
  The response object:
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "bundler/gem_tasks"
3
4
  require "rake/testtask"
5
+ require "rubocop/rake_task"
4
6
 
5
7
  Rake::TestTask.new(:test) do |t|
6
8
  t.libs << "test"
@@ -8,4 +10,6 @@ Rake::TestTask.new(:test) do |t|
8
10
  t.warning = false
9
11
  end
10
12
 
11
- task default: :test
13
+ RuboCop::RakeTask.new
14
+
15
+ task default: %i[test rubocop]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "./lib/aitch/version"
2
4
 
3
5
  Gem::Specification.new do |spec|
@@ -10,19 +12,21 @@ Gem::Specification.new do |spec|
10
12
  spec.homepage = "http://rubygems.org/gems/aitch"
11
13
  spec.license = "MIT"
12
14
 
13
- spec.files = `git ls-files`.split($/)
14
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
+ spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
15
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
18
  spec.require_paths = ["lib"]
17
19
 
18
- spec.required_ruby_version = ">= 2.0"
19
-
20
- spec.add_dependency "nokogiri", ">= 1.6.0"
20
+ spec.add_dependency "nokogiri"
21
21
 
22
- spec.add_development_dependency "codeclimate-test-reporter"
23
22
  spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "minitest"
25
24
  spec.add_development_dependency "minitest-utils"
26
25
  spec.add_development_dependency "mocha"
26
+ spec.add_development_dependency "pry-meta"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rubocop"
29
+ spec.add_development_dependency "rubocop-fnando"
30
+ spec.add_development_dependency "simplecov"
27
31
  spec.add_development_dependency "webmock"
28
32
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "net/https"
3
4
  require "forwardable"
4
5
  require "json"
@@ -38,21 +39,19 @@ module Aitch
38
39
  extend Forwardable
39
40
 
40
41
  def_delegators :namespace,
41
- :configuration, :config,
42
- :get, :get!,
43
- :post, :post!,
44
- :put, :put!,
45
- :patch, :patch!,
46
- :options, :options!,
47
- :trace, :trace!,
48
- :head, :head!,
49
- :delete, :delete!,
50
- :execute, :execute!,
51
- :configure
42
+ :configuration, :config,
43
+ :get, :get!,
44
+ :post, :post!,
45
+ :put, :put!,
46
+ :patch, :patch!,
47
+ :options, :options!,
48
+ :trace, :trace!,
49
+ :head, :head!,
50
+ :delete, :delete!,
51
+ :execute, :execute!,
52
+ :configure
52
53
  end
53
54
 
54
- private
55
-
56
55
  def self.namespace
57
56
  @namespace ||= Namespace.new
58
57
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Configuration
4
5
  # Set proxy.
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class DSL
4
5
  %w[url options headers data].each do |name|
5
- class_eval <<-RUBY
6
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
6
7
  attr_writer :#{name}
7
8
 
8
9
  def #{name}(*args)
@@ -12,8 +13,8 @@ module Aitch
12
13
  RUBY
13
14
  end
14
15
 
15
- alias_method :params, :data
16
- alias_method :body, :data
16
+ alias params data
17
+ alias body data
17
18
 
18
19
  def to_h
19
20
  {
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aitch
2
4
  module Engines
3
5
  module JSON
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  InvalidURIError = Class.new(StandardError)
4
5
  InvalidHTTPMethodError = Class.new(StandardError)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "cgi"
3
4
 
4
5
  class Object
@@ -39,20 +40,21 @@ class Array
39
40
  # Calls <tt>to_param</tt> on all its elements and joins the result with
40
41
  # slashes. This is used by <tt>url_for</tt> in Action Pack.
41
42
  def to_param
42
- collect { |e| e.to_param }.join '/'
43
+ collect(&:to_param).join "/"
43
44
  end
44
45
 
45
46
  # Converts an array into a string suitable for use as a URL query string,
46
47
  # using the given +key+ as the param name.
47
48
  #
48
- # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
49
+ # ["Rails", "coding"].to_query("hobbies")
50
+ # # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
49
51
  def to_query(key)
50
52
  prefix = "#{key}[]"
51
53
 
52
54
  if empty?
53
55
  nil.to_query(prefix)
54
56
  else
55
- collect { |value| value.to_query(prefix) }.join '&'
57
+ collect {|value| value.to_query(prefix) }.join "&"
56
58
  end
57
59
  end
58
60
  end
@@ -78,8 +80,8 @@ class Hash
78
80
  unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
79
81
  value.to_query(namespace ? "#{namespace}[#{key}]" : key)
80
82
  end
81
- end.compact.sort! * '&'
83
+ end.compact.sort! * "&"
82
84
  end
83
85
 
84
- alias_method :to_param, :to_query
86
+ alias to_param to_query
85
87
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Location
4
5
  attr_reader :redirect_stack, :current_url
@@ -9,7 +10,7 @@ module Aitch
9
10
  end
10
11
 
11
12
  def location
12
- return current_url unless current_url.match(%r[\A/])
13
+ return current_url unless current_url.match(%r{\A/})
13
14
 
14
15
  uri = find_uri_with_host
15
16
  url = ["#{uri.scheme}://#{uri.hostname}"]
@@ -20,8 +21,8 @@ module Aitch
20
21
 
21
22
  def find_uri_with_host
22
23
  redirect_stack.reverse
23
- .map {|url| ::URI.parse(url) }
24
- .find {|uri| uri.scheme }
24
+ .map {|url| ::URI.parse(url) }
25
+ .find(&:scheme)
25
26
  end
26
27
  end
27
28
  end
@@ -1,16 +1,30 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Namespace
4
- def configure(&block)
5
+ def configure
5
6
  yield config
6
7
  end
7
8
 
8
9
  def config
9
10
  @config ||= Configuration.new
10
11
  end
11
- alias_method :configuration, :config
12
+ alias configuration config
13
+
14
+ def execute(
15
+ request_method: nil,
16
+ url: nil,
17
+ params: nil,
18
+ data: nil,
19
+ body: nil,
20
+ headers: nil,
21
+ options: nil,
22
+ &block
23
+ )
24
+ data = data || params || body || {}
25
+ headers ||= {}
26
+ options ||= {}
12
27
 
13
- def execute(request_method = nil, url = nil, data = {}, headers = {}, options = {}, &block)
14
28
  if block_given?
15
29
  dsl = DSL.new
16
30
  dsl.instance_eval(&block)
@@ -33,8 +47,11 @@ module Aitch
33
47
  end
34
48
 
35
49
  def execute!(*args, &block)
36
- response = execute(*args, &block)
50
+ options = extract_args!(args)
51
+ response = execute(**options, &block)
52
+
37
53
  raise response.error if response.error?
54
+
38
55
  response
39
56
  end
40
57
 
@@ -47,14 +64,23 @@ module Aitch
47
64
  options
48
65
  trace
49
66
  head
50
- ].each do |method_name|
51
- define_method(method_name) do |url = nil, data = {}, headers = {}, options = {}, &block|
52
- execute(method_name, url, data, headers, options, &block)
67
+ ].each do |request_method|
68
+ define_method(request_method) do |*args, &block|
69
+ options = extract_args!(args)
70
+ execute(**options.merge(request_method: request_method), &block)
53
71
  end
54
72
 
55
- define_method("#{method_name}!") do |url = nil, data = {}, headers = {}, options = {}, &block|
56
- execute!(method_name, url, data, headers, options, &block)
73
+ define_method("#{request_method}!") do |*args, &block|
74
+ options = extract_args!(args)
75
+
76
+ execute!(**options.merge(request_method: request_method), &block)
57
77
  end
58
78
  end
79
+
80
+ private def extract_args!(args)
81
+ return args.first if args.size == 1 && args.first.is_a?(Hash)
82
+
83
+ %i[url data headers options].zip(args).to_h
84
+ end
59
85
  end
60
86
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Redirect
4
5
  attr_reader :tries
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Request
4
5
  attr_accessor :request_method
@@ -8,6 +9,9 @@ module Aitch
8
9
  attr_accessor :options
9
10
  attr_accessor :redirects
10
11
 
12
+ alias params= data=
13
+ alias body= data=
14
+
11
15
  def initialize(options)
12
16
  self.headers = {}
13
17
  self.options = {}
@@ -35,7 +39,8 @@ module Aitch
35
39
  end
36
40
 
37
41
  def content_type
38
- headers["Content-Type"] || options.fetch(:default_headers, {})["Content-Type"]
42
+ headers["Content-Type"] ||
43
+ options.fetch(:default_headers, {})["Content-Type"]
39
44
  end
40
45
 
41
46
  def request
@@ -63,23 +68,26 @@ module Aitch
63
68
  def http_method_class
64
69
  Net::HTTP.const_get(request_method.to_s.capitalize)
65
70
  rescue NameError
66
- raise InvalidHTTPMethodError, "unexpected HTTP verb: #{request_method.inspect}"
71
+ raise InvalidHTTPMethodError,
72
+ "unexpected HTTP verb: #{request_method.inspect}"
67
73
  end
68
74
 
69
- private
70
- def set_body(request)
75
+ private def set_body(request)
71
76
  body_data = data
72
77
  body_data = data.to_h if data.respond_to?(:to_h)
73
- body_data = ResponseParser::JSONParser.engine.dump(body_data) if content_type.to_s =~ /\bjson\b/
74
78
 
75
- if body_data.kind_of?(Hash)
76
- request.body = Utils.build_query(body_data)
77
- else
78
- request.body = body_data.to_s
79
+ if content_type.to_s =~ /\bjson\b/
80
+ body_data = ResponseParser::JSONParser.engine.dump(body_data)
79
81
  end
82
+
83
+ request.body = if body_data.is_a?(Hash)
84
+ Utils.build_query(body_data)
85
+ else
86
+ body_data.to_s
87
+ end
80
88
  end
81
89
 
82
- def set_headers(request)
90
+ private def set_headers(request)
83
91
  all_headers = options.fetch(:default_headers, {}).merge(headers)
84
92
 
85
93
  all_headers.each do |name, value|
@@ -88,30 +96,31 @@ module Aitch
88
96
  end
89
97
  end
90
98
 
91
- def set_credentials(request)
99
+ private def set_credentials(request)
92
100
  return unless options[:user] || options[:password]
101
+
93
102
  request.basic_auth(options[:user], options[:password])
94
103
  end
95
104
 
96
- def set_https(client)
105
+ private def set_https(client)
97
106
  client.use_ssl = uri.scheme == "https"
98
107
  client.verify_mode = OpenSSL::SSL::VERIFY_PEER
99
108
  end
100
109
 
101
- def set_timeout(client)
110
+ private def set_timeout(client)
102
111
  client.read_timeout = options[:timeout]
103
112
  end
104
113
 
105
- def set_logger(client)
114
+ private def set_logger(client)
106
115
  logger = options[:logger]
107
116
  client.set_debug_output(logger) if logger
108
117
  end
109
118
 
110
- def set_user_agent(request)
119
+ private def set_user_agent(request)
111
120
  request["User-Agent"] = options[:user_agent]
112
121
  end
113
122
 
114
- def set_gzip(request)
123
+ private def set_gzip(request)
115
124
  request["Accept-Encoding"] = "gzip,deflate"
116
125
  end
117
126
 
@@ -119,7 +128,7 @@ module Aitch
119
128
  defined?(Net::ReadTimeout) ? Net::ReadTimeout : Timeout::Error
120
129
  end
121
130
 
122
- def follow_redirect(response, redirected_from = [])
131
+ private def follow_redirect(response)
123
132
  return response unless response.redirect?
124
133
 
125
134
  redirect = Redirect.new(options)
@@ -143,18 +152,18 @@ module Aitch
143
152
  response
144
153
  end
145
154
 
146
- def validate_response!(response)
155
+ private def validate_response!(response)
147
156
  return unless options[:expect]
148
157
 
149
158
  expected = [options[:expect]].flatten
150
159
  return if expected.include?(response.code)
151
160
 
152
161
  descriptions = expected
153
- .map {|code| Response.description_for_code(code) }
154
- .join(", ")
162
+ .map {|code| Response.description_for_code(code) }
163
+ .join(", ")
155
164
 
156
165
  raise StatusCodeError,
157
- "Expected(#{descriptions}) <=> Actual(#{response.description})"
166
+ "Expected(#{descriptions}) <=> Actual(#{response.description})"
158
167
  end
159
168
  end
160
169
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Response
4
5
  extend Forwardable
@@ -17,7 +18,9 @@ module Aitch
17
18
  end
18
19
 
19
20
  ERRORS.each do |status_code, exception|
20
- method_name = Utils.underscore(exception.name.split("::").last).gsub("_error", "")
21
+ method_name = Utils
22
+ .underscore(exception.name.split("::").last)
23
+ .gsub("_error", "")
21
24
 
22
25
  define_method "#{method_name}?" do
23
26
  code == status_code
@@ -35,7 +38,7 @@ module Aitch
35
38
  def success?
36
39
  code >= 200 && code <= 399
37
40
  end
38
- alias_method :ok?, :success?
41
+ alias ok? success?
39
42
 
40
43
  def redirect?
41
44
  code >= 300 && code <= 399
@@ -75,10 +78,11 @@ module Aitch
75
78
 
76
79
  def method_missing(name, *args, &block)
77
80
  return headers[name.to_s] if headers.key?(name.to_s)
81
+
78
82
  super
79
83
  end
80
84
 
81
- def respond_to_missing?(name, include_private = false)
85
+ def respond_to_missing?(name, _include_private = false)
82
86
  headers.key?(name.to_s)
83
87
  end
84
88
 
@@ -90,6 +94,6 @@ module Aitch
90
94
  "#<#{self.class} #{description} (#{content_type})>"
91
95
  end
92
96
 
93
- alias_method :to_s, :inspect
97
+ alias to_s inspect
94
98
  end
95
99
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Response
4
5
  class Body
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Response
4
5
  DESCRIPTION = {
@@ -56,7 +57,7 @@ module Aitch
56
57
  504 => "Gateway Time Out",
57
58
  505 => "Version Not Supported",
58
59
  507 => "Insufficient Storage",
59
- 511 => "Network Authentication Required",
60
- }
60
+ 511 => "Network Authentication Required"
61
+ }.freeze
61
62
  end
62
63
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class Response
4
5
  ERRORS = {
@@ -35,6 +36,6 @@ module Aitch
35
36
  505 => VersionNotSupportedError,
36
37
  507 => InsufficientStorageError,
37
38
  511 => NetworkAuthenticationRequiredError
38
- }
39
+ }.freeze
39
40
  end
40
41
  end
@@ -1,24 +1,27 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  module ResponseParser
4
- PARSERS = []
5
+ def self.parsers
6
+ @parsers ||= []
7
+ end
5
8
 
6
9
  def self.prepend(name, parser)
7
10
  unregister(name)
8
- PARSERS.unshift parser
11
+ parsers.unshift parser
9
12
  end
10
13
 
11
14
  def self.append(name, parser)
12
15
  unregister(name)
13
- PARSERS << parser
16
+ parsers << parser
14
17
  end
15
18
 
16
19
  def self.unregister(name)
17
- PARSERS.delete_if {|parser| parser.type == name }
20
+ parsers.delete_if {|parser| parser.type == name }
18
21
  end
19
22
 
20
23
  def self.find(content_type)
21
- PARSERS.find {|parser| parser.match?(content_type) }
24
+ parsers.find {|parser| parser.match?(content_type) }
22
25
  end
23
26
 
24
27
  append :json, JSONParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  module ResponseParser
4
5
  module DefaultParser
@@ -6,7 +7,7 @@ module Aitch
6
7
  :default
7
8
  end
8
9
 
9
- def self.match?(content_type)
10
+ def self.match?(_content_type)
10
11
  true
11
12
  end
12
13
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  module ResponseParser
4
5
  module HTMLParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  module ResponseParser
4
5
  module JSONParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  module ResponseParser
4
5
  module XMLParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
4
  class URI
4
5
  extend Forwardable
@@ -12,8 +13,8 @@ module Aitch
12
13
 
13
14
  begin
14
15
  @uri = ::URI.parse(url)
15
- rescue ::URI::InvalidURIError => error
16
- raise InvalidURIError, error
16
+ rescue ::URI::InvalidURIError => e
17
+ raise InvalidURIError, e
17
18
  end
18
19
  end
19
20
 
@@ -35,7 +36,9 @@ module Aitch
35
36
 
36
37
  def query
37
38
  query = [@uri.query]
38
- query << ::URI.encode_www_form(@data.to_a) if !request_has_body? && @data.respond_to?(:to_a)
39
+ if !request_has_body? && @data.respond_to?(:to_a)
40
+ query << ::URI.encode_www_form(@data.to_a)
41
+ end
39
42
  query = query.compact.reject(&:empty?).join("&")
40
43
 
41
44
  "?#{query}" unless query == ""
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
- module Utils extend self
4
+ module Utils
5
+ extend self
4
6
  def underscore(string)
5
7
  string = string.gsub(/(?<=.)(URI|[A-Z])/) do |char|
6
8
  "_#{char}"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aitch
3
- VERSION = "1.0.2"
4
+ VERSION = "1.1.0"
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class AitchTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class ConfigurationTest < Minitest::Test
@@ -16,7 +17,7 @@ class ConfigurationTest < Minitest::Test
16
17
  end
17
18
 
18
19
  test "sets default headers" do
19
- assert_equal Hash.new, Aitch::Configuration.new.default_headers
20
+ assert_equal({}, Aitch::Configuration.new.default_headers)
20
21
  end
21
22
 
22
23
  test "configures aitch" do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class DslTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class ExecuteTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class NamespaceTest < Minitest::Test
@@ -7,6 +8,6 @@ class NamespaceTest < Minitest::Test
7
8
  ns.config.user_agent = "MyLib/1.0.0"
8
9
 
9
10
  assert_equal "MyLib/1.0.0", ns.config.user_agent
10
- assert_match %r[^Aitch], Aitch.config.user_agent
11
+ assert_match(/^Aitch/, Aitch.config.user_agent)
11
12
  end
12
13
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class ClientHttpsTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class FollowRedirectTest < Minitest::Test
@@ -25,9 +26,9 @@ class FollowRedirectTest < Minitest::Test
25
26
  register_uri(:get, "http://example.org/", location: "http://example.com/", status: 301)
26
27
  register_uri(:get, "http://example.com/", location: "https://example.com/", status: 301)
27
28
 
28
- assert_raises(Aitch::TooManyRedirectsError) {
29
+ assert_raises(Aitch::TooManyRedirectsError) do
29
30
  Aitch.get("http://example.org/")
30
- }
31
+ end
31
32
  end
32
33
 
33
34
  test "returns only redirection urls" do
@@ -50,7 +51,7 @@ class FollowRedirectTest < Minitest::Test
50
51
  register_uri(:post, "http://example.org/hi", status: 307, location: "/hello")
51
52
  register_uri(:post, "http://example.org/hello", status: 200)
52
53
 
53
- response = Aitch.post("http://example.org/", {a: 1}, {Range: "1..100"})
54
+ response = Aitch.post("http://example.org/", {a: 1}, Range: "1..100")
54
55
 
55
56
  assert_equal "http://example.org/hello", response.url
56
57
  assert_equal 200, response.code
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class JsonRequestTest < Minitest::Test
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class RequestClassTest < Minitest::Test
5
6
  test "raises with invalid method" do
6
- error = assert_raises(Aitch::InvalidHTTPMethodError) {
7
+ error = assert_raises(Aitch::InvalidHTTPMethodError) do
7
8
  build_request(request_method: "invalid").request
8
- }
9
+ end
9
10
 
10
11
  assert_equal %[unexpected HTTP verb: "invalid"], error.message
11
12
  end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class StatusCodeValidationTest < Minitest::Test
5
6
  test "raises exception when status code isn't valid" do
6
7
  register_uri(:get, "http://example.org/", status: 404)
7
8
 
8
- error = assert_raises(Aitch::StatusCodeError) {
9
+ error = assert_raises(Aitch::StatusCodeError) do
9
10
  Aitch.get("http://example.org/", {}, {}, expect: [200])
10
- }
11
+ end
11
12
 
12
13
  assert_equal "Expected(200 OK) <=> Actual(404 Not Found)", error.message
13
14
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class RequestTest < Minitest::Test
5
6
  test "sets content type" do
6
- request = build_request(content_type: 'application/json')
7
- assert_equal 'application/json', request.content_type
7
+ request = build_request(content_type: "application/json")
8
+ assert_equal "application/json", request.content_type
8
9
  end
9
10
 
10
11
  test "raises with invalid uri" do
@@ -25,9 +26,11 @@ class RequestTest < Minitest::Test
25
26
  end
26
27
 
27
28
  test "sets user agent" do
28
- requester = build_request
29
+ requester = build_request(headers: {"User-Agent" => "CUSTOM"})
29
30
  request = requester.request
30
- assert_equal requester.options[:user_agent], request["User-Agent"]
31
+
32
+ assert_equal "CUSTOM", requester.headers["User-Agent"]
33
+ assert_equal "CUSTOM", request["User-Agent"]
31
34
  end
32
35
 
33
36
  test "requests gzip encoding" do
@@ -50,6 +53,11 @@ class RequestTest < Minitest::Test
50
53
  assert_equal "some body", request.body
51
54
  end
52
55
 
56
+ test "sets request body from params key" do
57
+ request = build_request(request_method: "post", params: "some body").request
58
+ assert_equal "some body", request.body
59
+ end
60
+
53
61
  test "sets json body from object" do
54
62
  request = build_request(
55
63
  request_method: "post",
@@ -66,7 +74,7 @@ class RequestTest < Minitest::Test
66
74
  request = build_request(
67
75
  request_method: "post",
68
76
  data: {a: 1},
69
- options: {json_parser: JSON, default_headers: {'Content-Type' => 'application/json'}}
77
+ options: {json_parser: JSON, default_headers: {"Content-Type" => "application/json"}}
70
78
  ).request
71
79
 
72
80
  expected = {a: 1}.to_json
@@ -121,7 +129,7 @@ class RequestTest < Minitest::Test
121
129
  test "performs request when using dsl" do
122
130
  register_uri(:post, /.+/)
123
131
 
124
- response = Aitch.post do
132
+ Aitch.post do
125
133
  url "http://example.org/some/path"
126
134
  params a: 1, b: 2
127
135
  headers Rendering: "0.1"
@@ -134,4 +142,21 @@ class RequestTest < Minitest::Test
134
142
  assert_equal "0.1", last_request.headers["Rendering"]
135
143
  assert_equal "user:pass", Base64.decode64(last_request.headers["Authorization"].split(" ").last)
136
144
  end
145
+
146
+ test "performs request when using kwargs" do
147
+ register_uri(:post, /.+/)
148
+
149
+ Aitch.post(
150
+ url: "http://example.org/some/path",
151
+ data: {a: 1, b: 2},
152
+ headers: {Rendering: "0.1"},
153
+ options: {user: "user", password: "pass"}
154
+ )
155
+
156
+ assert_equal "/some/path", last_request.uri.request_uri
157
+ assert_equal :post, last_request.method
158
+ assert_equal "a=1&b=2", last_request.body
159
+ assert_equal "0.1", last_request.headers["Rendering"]
160
+ assert_equal "user:pass", Base64.decode64(last_request.headers["Authorization"].split(" ").last)
161
+ end
137
162
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
  require "csv"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class ErrorsTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class HtmlResponseTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class JsonResponseTest < Minitest::Test
@@ -13,6 +14,6 @@ class JsonResponseTest < Minitest::Test
13
14
  register_uri(:get, "http://example.org/", body: "[1,2,3]", content_type: "application/json")
14
15
  response = Aitch.get("http://example.org/")
15
16
 
16
- assert_equal [1,2,3], response.data
17
+ assert_equal [1, 2, 3], response.data
17
18
  end
18
19
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class RawResponseTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class Status3xxTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class Status4xxTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class Status5xxTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class XmlResponseTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class HtmlParserTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class JsonParserTest < Minitest::Test
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
2
+
3
3
  require "test_helper"
4
4
 
5
5
  class XmlParserTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class ResponseTest < Minitest::Test
@@ -27,7 +28,6 @@ class ResponseTest < Minitest::Test
27
28
  end
28
29
 
29
30
  test "deflates response" do
30
- stdio = StringIO.new
31
31
  deflated = Zlib::Deflate.deflate("Hello")
32
32
 
33
33
  register_uri(:get, "http://example.org/", body: deflated, content_encoding: "deflate")
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class UriTest < Minitest::Test
@@ -27,7 +28,7 @@ class UriTest < Minitest::Test
27
28
  end
28
29
 
29
30
  test "ignores data when request has body" do
30
- assert_equal nil, Aitch::URI.new("http://example.org/", {c: 3}, true).query
31
+ assert_nil Aitch::URI.new("http://example.org/", {c: 3}, true).query
31
32
  end
32
33
 
33
34
  test "returns request uri" do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class SymbolizeKeysTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "test_helper"
3
4
 
4
5
  class UnderscoreTest < Minitest::Test
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Minitest
3
4
  class Test
4
5
  def add_hash_entry(source, target, from, to)
@@ -6,13 +7,13 @@ module Minitest
6
7
  end
7
8
 
8
9
  def register_uri(http_method, url, options = {})
9
- body = options.fetch(:body, '')
10
+ body = options.fetch(:body, "")
10
11
  status = options.fetch(:status, 200)
11
12
  headers = options.fetch(:headers, {})
12
13
 
13
- add_hash_entry(options, headers, :location, 'Location')
14
- add_hash_entry(options, headers, :content_type, 'Content-Type')
15
- add_hash_entry(options, headers, :content_encoding, 'Content-Encoding')
14
+ add_hash_entry(options, headers, :location, "Location")
15
+ add_hash_entry(options, headers, :content_type, "Content-Type")
16
+ add_hash_entry(options, headers, :content_encoding, "Content-Encoding")
16
17
 
17
18
  stub_request(http_method, url)
18
19
  .to_return(status: status, body: body, headers: headers)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require "codeclimate-test-reporter"
3
- CodeClimate::TestReporter.start
2
+
3
+ require "simplecov"
4
+ SimpleCov.start
4
5
 
5
6
  require "bundler/setup"
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aitch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-27 00:00:00.000000000 Z
11
+ date: 2020-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -16,16 +16,16 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: codeclimate-test-reporter
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,49 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-utils
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-meta
43
85
  requirement: !ruby/object:Gem::Requirement
44
86
  requirements:
45
87
  - - ">="
@@ -67,7 +109,7 @@ dependencies:
67
109
  - !ruby/object:Gem::Version
68
110
  version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
- name: minitest-utils
112
+ name: rubocop
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - ">="
@@ -81,7 +123,21 @@ dependencies:
81
123
  - !ruby/object:Gem::Version
82
124
  version: '0'
83
125
  - !ruby/object:Gem::Dependency
84
- name: mocha
126
+ name: rubocop-fnando
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
85
141
  requirement: !ruby/object:Gem::Requirement
86
142
  requirements:
87
143
  - - ">="
@@ -116,6 +172,7 @@ extensions: []
116
172
  extra_rdoc_files: []
117
173
  files:
118
174
  - ".gitignore"
175
+ - ".rubocop.yml"
119
176
  - ".travis.yml"
120
177
  - CHANGELOG.md
121
178
  - Gemfile
@@ -187,15 +244,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
244
  requirements:
188
245
  - - ">="
189
246
  - !ruby/object:Gem::Version
190
- version: '2.0'
247
+ version: '0'
191
248
  required_rubygems_version: !ruby/object:Gem::Requirement
192
249
  requirements:
193
250
  - - ">="
194
251
  - !ruby/object:Gem::Version
195
252
  version: '0'
196
253
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.5.1
254
+ rubygems_version: 3.1.2
199
255
  signing_key:
200
256
  specification_version: 4
201
257
  summary: A simple HTTP client