aitch 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -1
- data/.travis.yml +13 -3
- data/Gemfile +1 -1
- data/README.md +22 -3
- data/aitch.gemspec +3 -6
- data/lib/aitch.rb +7 -1
- data/lib/aitch/errors.rb +1 -0
- data/lib/aitch/ext/to_query.rb +84 -0
- data/lib/aitch/request.rb +34 -13
- data/lib/aitch/response.rb +9 -1
- data/lib/aitch/response/description.rb +61 -0
- data/lib/aitch/version.rb +1 -1
- data/spec/aitch/aitch_spec.rb +1 -1
- data/spec/aitch/configuration_spec.rb +6 -6
- data/spec/aitch/dsl_spec.rb +6 -6
- data/spec/aitch/namespace_spec.rb +1 -1
- data/spec/aitch/request_spec.rb +60 -35
- data/spec/aitch/response_spec.rb +89 -44
- data/spec/aitch/uri_spec.rb +8 -8
- data/spec/aitch/utils_spec.rb +3 -3
- data/spec/aitch/xml_parser_spec.rb +1 -1
- data/spec/spec_helper.rb +6 -2
- data/spec/support/request_uri.rb +24 -0
- data/spec/support/webmock.rb +15 -0
- metadata +12 -8
- data/.coveralls.yml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23b168b3e1919c4678e936b498d68f03d76d633e
|
4
|
+
data.tar.gz: a389c8c536ca656791eb7eae62f2f74b15a62983
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 355b7f2f6bb8cabf5defde1bfe2bf8dbeb0ca7d545d3f70c6e92ccfa1b08193d295bb859774306e76641a9b6f2854b08b75bd483f78453f1bd6eefb9748b3b65
|
7
|
+
data.tar.gz: d3dfa452ba5bb4c8483315372b966d45765e7d480f7a52cced117c58e131c15fa4f8a6c9e133f56090b2fbfcc48f8b62cf93e61fee890b1a3a2498c1998d0b17
|
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color --order random
|
1
|
+
--color --order random
|
data/.travis.yml
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
language: ruby
|
2
2
|
script: "bundle exec rspec"
|
3
|
+
before_install: gem install bundler
|
4
|
+
cache: bundler
|
5
|
+
sudo: false
|
3
6
|
|
4
7
|
rvm:
|
5
|
-
- 2.
|
6
|
-
- 2.
|
7
|
-
-
|
8
|
+
- "2.2"
|
9
|
+
- "2.1"
|
10
|
+
- "2.0"
|
11
|
+
- "1.9"
|
8
12
|
- jruby-19mode
|
13
|
+
- jruby-head
|
9
14
|
|
10
15
|
gemfile:
|
11
16
|
- Gemfile
|
@@ -13,3 +18,8 @@ gemfile:
|
|
13
18
|
notifications:
|
14
19
|
email:
|
15
20
|
- fnando.vieira@gmail.com
|
21
|
+
|
22
|
+
addons:
|
23
|
+
code_climate:
|
24
|
+
repo_token:
|
25
|
+
secure: "j/AjAG1u7NtdldftKUXnTMKC7CPd2R/O55ejzZnJi5IlHKKKZgJla1Z0YHTsGr75JQS7Q00D0L3TOSY8fLhV6fXO3Gn+9ShKTFRV5+iUtzlV0AWKBw+uENKNJH4jn1FhCoV8Th0I6OKtq98PqZ/hLR2J+/Uv3oCBwyriyJqag2U="
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Aitch
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/fnando/aitch.png)](https://travis-ci.org/fnando/aitch)
|
4
|
-
[![
|
4
|
+
[![Code Climate](https://codeclimate.com/github/fnando/aitch/badges/gpa.svg)](https://codeclimate.com/github/fnando/aitch)
|
5
|
+
[![Test Coverage](https://codeclimate.com/github/fnando/aitch/badges/coverage.svg)](https://codeclimate.com/github/fnando/aitch)
|
5
6
|
[![RubyGems](https://badge.fury.io/rb/aitch.png)](https://rubygems.org/gems/aitch)
|
6
|
-
[![Coveralls](https://coveralls.io/repos/fnando/aitch/badge.png?branch=master)](https://coveralls.io/r/fnando/aitch)
|
7
7
|
|
8
8
|
A simple HTTP client.
|
9
9
|
|
@@ -169,7 +169,7 @@ Setting basic auth credentials:
|
|
169
169
|
```ruby
|
170
170
|
response = Aitch.get do
|
171
171
|
url "http://restrict.example.org/"
|
172
|
-
options
|
172
|
+
options user: "john", password: "test"
|
173
173
|
end
|
174
174
|
```
|
175
175
|
|
@@ -206,6 +206,25 @@ end
|
|
206
206
|
Request.get("http://example.org")
|
207
207
|
```
|
208
208
|
|
209
|
+
### Validating responses
|
210
|
+
|
211
|
+
When you know of kind of response you're expecting, you can validate the response with a list of accepted response statuses.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
Aitch.get do
|
215
|
+
url "http://example.org"
|
216
|
+
options expect: 200
|
217
|
+
end
|
218
|
+
```
|
219
|
+
|
220
|
+
If this request receives anything other than `200`, it will raise a `Aitch::StatusCodeError` exception.
|
221
|
+
|
222
|
+
```
|
223
|
+
Expect(200 OK) <=> Actual(404 Not Found)
|
224
|
+
```
|
225
|
+
|
226
|
+
You can also provide a list of accepted statuses, like `expect: [200, 201]`.
|
227
|
+
|
209
228
|
## Contributing
|
210
229
|
|
211
230
|
1. Fork it
|
data/aitch.gemspec
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'aitch/version'
|
1
|
+
require "./lib/aitch/version"
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
4
|
spec.name = "aitch"
|
@@ -19,11 +16,11 @@ Gem::Specification.new do |spec|
|
|
19
16
|
spec.require_paths = ["lib"]
|
20
17
|
|
21
18
|
spec.add_dependency "nokogiri", ">= 1.6.0"
|
22
|
-
spec.add_dependency "activesupport"
|
23
19
|
|
20
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
24
21
|
spec.add_development_dependency "bundler"
|
25
22
|
spec.add_development_dependency "rake"
|
26
23
|
spec.add_development_dependency "rspec"
|
27
24
|
spec.add_development_dependency "test_notifier"
|
28
|
-
spec.add_development_dependency "
|
25
|
+
spec.add_development_dependency "webmock"
|
29
26
|
end
|
data/lib/aitch.rb
CHANGED
@@ -4,7 +4,12 @@ require "json"
|
|
4
4
|
require "zlib"
|
5
5
|
|
6
6
|
require "nokogiri"
|
7
|
-
|
7
|
+
|
8
|
+
begin
|
9
|
+
require "active_support/core_ext/object/to_query"
|
10
|
+
rescue LoadError
|
11
|
+
require "aitch/ext/to_query"
|
12
|
+
end
|
8
13
|
|
9
14
|
require "aitch/utils"
|
10
15
|
require "aitch/uri"
|
@@ -18,6 +23,7 @@ require "aitch/redirect"
|
|
18
23
|
require "aitch/response/errors"
|
19
24
|
require "aitch/response"
|
20
25
|
require "aitch/response/body"
|
26
|
+
require "aitch/response/description"
|
21
27
|
require "aitch/xml_parser"
|
22
28
|
require "aitch/html_parser"
|
23
29
|
require "aitch/version"
|
data/lib/aitch/errors.rb
CHANGED
@@ -3,6 +3,7 @@ module Aitch
|
|
3
3
|
InvalidHTTPMethodError = Class.new(StandardError)
|
4
4
|
RequestTimeoutError = Class.new(StandardError)
|
5
5
|
TooManyRedirectsError = Class.new(StandardError)
|
6
|
+
StatusCodeError = Class.new(StandardError)
|
6
7
|
|
7
8
|
ResponseError = Class.new(StandardError)
|
8
9
|
BadRequestError = Class.new(ResponseError)
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "cgi"
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Alias of <tt>to_s</tt>.
|
5
|
+
def to_param
|
6
|
+
to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
# Converts an object into a string suitable for use as a URL query string,
|
10
|
+
# using the given <tt>key</tt> as the param name.
|
11
|
+
def to_query(key)
|
12
|
+
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class NilClass
|
17
|
+
# Returns +self+.
|
18
|
+
def to_param
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class TrueClass
|
24
|
+
# Returns +self+.
|
25
|
+
def to_param
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class FalseClass
|
31
|
+
# Returns +self+.
|
32
|
+
def to_param
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Array
|
38
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
39
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
40
|
+
def to_param
|
41
|
+
collect { |e| e.to_param }.join '/'
|
42
|
+
end
|
43
|
+
|
44
|
+
# Converts an array into a string suitable for use as a URL query string,
|
45
|
+
# using the given +key+ as the param name.
|
46
|
+
#
|
47
|
+
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
48
|
+
def to_query(key)
|
49
|
+
prefix = "#{key}[]"
|
50
|
+
|
51
|
+
if empty?
|
52
|
+
nil.to_query(prefix)
|
53
|
+
else
|
54
|
+
collect { |value| value.to_query(prefix) }.join '&'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Hash
|
60
|
+
# Returns a string representation of the receiver suitable for use as a URL
|
61
|
+
# query string:
|
62
|
+
#
|
63
|
+
# {name: 'David', nationality: 'Danish'}.to_query
|
64
|
+
# # => "name=David&nationality=Danish"
|
65
|
+
#
|
66
|
+
# An optional namespace can be passed to enclose key names:
|
67
|
+
#
|
68
|
+
# {name: 'David', nationality: 'Danish'}.to_query('user')
|
69
|
+
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
70
|
+
#
|
71
|
+
# The string pairs "key=value" that conform the query string
|
72
|
+
# are sorted lexicographically in ascending order.
|
73
|
+
#
|
74
|
+
# This method is also aliased as +to_param+.
|
75
|
+
def to_query(namespace = nil)
|
76
|
+
collect do |key, value|
|
77
|
+
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
78
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
79
|
+
end
|
80
|
+
end.compact.sort! * '&'
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :to_param, :to_query
|
84
|
+
end
|
data/lib/aitch/request.rb
CHANGED
@@ -18,18 +18,8 @@ module Aitch
|
|
18
18
|
def perform
|
19
19
|
response = Response.new(options, client.request(request))
|
20
20
|
response.url = url
|
21
|
-
|
22
|
-
|
23
|
-
while redirect.follow?(response)
|
24
|
-
redirected_from ||= [url]
|
25
|
-
redirected_from << Location.new(redirected_from, response.location).location
|
26
|
-
redirect.followed!
|
27
|
-
response = Aitch.get(redirected_from.last)
|
28
|
-
end
|
29
|
-
|
30
|
-
raise TooManyRedirectsError if redirect.enabled? && response.redirect?
|
31
|
-
|
32
|
-
response.redirected_from = redirected_from
|
21
|
+
response = follow_redirect(response)
|
22
|
+
validate_response! response
|
33
23
|
response
|
34
24
|
rescue timeout_exception
|
35
25
|
raise RequestTimeoutError
|
@@ -94,7 +84,8 @@ module Aitch
|
|
94
84
|
end
|
95
85
|
|
96
86
|
def set_credentials(request)
|
97
|
-
|
87
|
+
return unless options[:user] || options[:password]
|
88
|
+
request.basic_auth(options[:user], options[:password])
|
98
89
|
end
|
99
90
|
|
100
91
|
def set_https(client)
|
@@ -122,5 +113,35 @@ module Aitch
|
|
122
113
|
def timeout_exception
|
123
114
|
defined?(Net::ReadTimeout) ? Net::ReadTimeout : Timeout::Error
|
124
115
|
end
|
116
|
+
|
117
|
+
def follow_redirect(response)
|
118
|
+
redirect = Redirect.new(options)
|
119
|
+
|
120
|
+
while redirect.follow?(response)
|
121
|
+
redirected_from ||= [url]
|
122
|
+
redirected_from << Location.new(redirected_from, response.location).location
|
123
|
+
redirect.followed!
|
124
|
+
response = Aitch.get(redirected_from.last)
|
125
|
+
end
|
126
|
+
|
127
|
+
raise TooManyRedirectsError if redirect.enabled? && response.redirect?
|
128
|
+
|
129
|
+
response.redirected_from = redirected_from
|
130
|
+
response
|
131
|
+
end
|
132
|
+
|
133
|
+
def validate_response!(response)
|
134
|
+
return unless options[:expect]
|
135
|
+
|
136
|
+
expected = [options[:expect]].flatten
|
137
|
+
return if expected.include?(response.code)
|
138
|
+
|
139
|
+
descriptions = expected
|
140
|
+
.map {|code| Response.description_for_code(code) }
|
141
|
+
.join(', ')
|
142
|
+
|
143
|
+
raise StatusCodeError,
|
144
|
+
"Expected(#{descriptions}) <=> Actual(#{response.description})"
|
145
|
+
end
|
125
146
|
end
|
126
147
|
end
|
data/lib/aitch/response.rb
CHANGED
@@ -5,6 +5,10 @@ module Aitch
|
|
5
5
|
def_delegators :@http_response, :content_type
|
6
6
|
attr_accessor :redirected_from, :url
|
7
7
|
|
8
|
+
def self.description_for_code(code)
|
9
|
+
[code, DESCRIPTION[code]].compact.join(' ')
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(options, http_response)
|
9
13
|
@options = options
|
10
14
|
@http_response = http_response
|
@@ -87,8 +91,12 @@ module Aitch
|
|
87
91
|
headers.key?(name.to_s)
|
88
92
|
end
|
89
93
|
|
94
|
+
def description
|
95
|
+
@description ||= self.class.description_for_code(code)
|
96
|
+
end
|
97
|
+
|
90
98
|
def inspect
|
91
|
-
"#<#{self.class} #{
|
99
|
+
"#<#{self.class} #{description} (#{content_type})>"
|
92
100
|
end
|
93
101
|
|
94
102
|
alias_method :to_s, :inspect
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Aitch
|
2
|
+
class Response
|
3
|
+
DESCRIPTION = {
|
4
|
+
100 => 'Continue',
|
5
|
+
101 => 'Switch Protocol',
|
6
|
+
|
7
|
+
200 => 'OK',
|
8
|
+
201 => 'Created',
|
9
|
+
202 => 'Accepted',
|
10
|
+
203 => 'Non Authoritative Information',
|
11
|
+
204 => 'No Content',
|
12
|
+
205 => 'Reset Content',
|
13
|
+
206 => 'Partial Content',
|
14
|
+
207 => 'Multi Status',
|
15
|
+
226 => 'IM Used',
|
16
|
+
|
17
|
+
300 => 'Multiple Choices',
|
18
|
+
301 => 'Moved Permanently',
|
19
|
+
302 => 'Found',
|
20
|
+
303 => 'See Other',
|
21
|
+
304 => 'Not Modified',
|
22
|
+
305 => 'Use Proxy',
|
23
|
+
307 => 'Temporary Redirect',
|
24
|
+
|
25
|
+
400 => 'Bad Request',
|
26
|
+
401 => 'Unauthorized',
|
27
|
+
402 => 'Payment Required',
|
28
|
+
403 => 'Forbidden',
|
29
|
+
404 => 'Not Found',
|
30
|
+
405 => 'Method Not Allowed',
|
31
|
+
406 => 'Not Acceptable',
|
32
|
+
407 => 'Proxy Authentication Required',
|
33
|
+
408 => 'Request Time Out',
|
34
|
+
409 => 'Conflict',
|
35
|
+
410 => 'Gone',
|
36
|
+
411 => 'Length Required',
|
37
|
+
412 => 'Precondition Failed',
|
38
|
+
413 => 'Request Entity Too Large',
|
39
|
+
414 => 'Request URIToo Long',
|
40
|
+
415 => 'Unsupported Media Type',
|
41
|
+
416 => 'Requested Range Not Satisfiable',
|
42
|
+
417 => 'Expectation Failed',
|
43
|
+
422 => 'Unprocessable Entity',
|
44
|
+
423 => 'Locked',
|
45
|
+
424 => 'Failed Dependency',
|
46
|
+
426 => 'Upgrade Required',
|
47
|
+
428 => 'Precondition Required',
|
48
|
+
429 => 'Too Many Requests',
|
49
|
+
431 => 'Request Header Fields Too Large',
|
50
|
+
|
51
|
+
500 => 'Internal Server Error',
|
52
|
+
501 => 'Not Implemented',
|
53
|
+
502 => 'Bad Gateway',
|
54
|
+
503 => 'Service Unavailable',
|
55
|
+
504 => 'Gateway Time Out',
|
56
|
+
505 => 'Version Not Supported',
|
57
|
+
507 => 'Insufficient Storage',
|
58
|
+
511 => 'Network Authentication Required',
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
data/lib/aitch/version.rb
CHANGED
data/spec/aitch/aitch_spec.rb
CHANGED
@@ -56,7 +56,7 @@ describe Aitch do
|
|
56
56
|
response = double(error?: false)
|
57
57
|
allow_any_instance_of(Aitch::Request).to receive(:perform).and_return(response)
|
58
58
|
|
59
|
-
expect(Aitch.get!("URL")).to
|
59
|
+
expect(Aitch.get!("URL")).to eq(response)
|
60
60
|
end
|
61
61
|
|
62
62
|
it "raises when has errors" do
|
@@ -2,24 +2,24 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Aitch::Configuration do
|
4
4
|
it "sets default timeout" do
|
5
|
-
expect(Aitch::Configuration.new.timeout).to
|
5
|
+
expect(Aitch::Configuration.new.timeout).to eq(10)
|
6
6
|
end
|
7
7
|
|
8
8
|
it "sets default user agent" do
|
9
9
|
user_agent = "Aitch/#{Aitch::VERSION} (http://rubygems.org/gems/aitch)"
|
10
|
-
expect(Aitch::Configuration.new.user_agent).to
|
10
|
+
expect(Aitch::Configuration.new.user_agent).to eq(user_agent)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "sets default maximum redirections" do
|
14
|
-
expect(Aitch::Configuration.new.redirect_limit).to
|
14
|
+
expect(Aitch::Configuration.new.redirect_limit).to eq(5)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "sets default headers" do
|
18
|
-
expect(Aitch::Configuration.new.default_headers).to
|
18
|
+
expect(Aitch::Configuration.new.default_headers).to eq({})
|
19
19
|
end
|
20
20
|
|
21
21
|
it "sets default XML parser" do
|
22
|
-
expect(Aitch::Configuration.new.xml_parser).to
|
22
|
+
expect(Aitch::Configuration.new.xml_parser).to eq(Aitch::XMLParser)
|
23
23
|
end
|
24
24
|
|
25
25
|
it "configures aitch" do
|
@@ -27,7 +27,7 @@ describe Aitch::Configuration do
|
|
27
27
|
config.timeout = 15
|
28
28
|
end
|
29
29
|
|
30
|
-
expect(Aitch.configuration.timeout).to
|
30
|
+
expect(Aitch.configuration.timeout).to eq(15)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/spec/aitch/dsl_spec.rb
CHANGED
@@ -5,32 +5,32 @@ describe Aitch::DSL do
|
|
5
5
|
|
6
6
|
it "sets url" do
|
7
7
|
dsl.url "URL"
|
8
|
-
expect(dsl.url).to
|
8
|
+
expect(dsl.url).to eq("URL")
|
9
9
|
end
|
10
10
|
|
11
11
|
it "sets options" do
|
12
12
|
dsl.options "OPTIONS"
|
13
|
-
expect(dsl.options).to
|
13
|
+
expect(dsl.options).to eq("OPTIONS")
|
14
14
|
end
|
15
15
|
|
16
16
|
it "sets headers" do
|
17
17
|
dsl.headers "HEADERS"
|
18
|
-
expect(dsl.headers).to
|
18
|
+
expect(dsl.headers).to eq("HEADERS")
|
19
19
|
end
|
20
20
|
|
21
21
|
it "sets data" do
|
22
22
|
dsl.data "DATA"
|
23
|
-
expect(dsl.data).to
|
23
|
+
expect(dsl.data).to eq("DATA")
|
24
24
|
end
|
25
25
|
|
26
26
|
it "sets data through params" do
|
27
27
|
dsl.params "PARAMS"
|
28
|
-
expect(dsl.data).to
|
28
|
+
expect(dsl.data).to eq("PARAMS")
|
29
29
|
end
|
30
30
|
|
31
31
|
it "sets data through body" do
|
32
32
|
dsl.body "BODY"
|
33
|
-
expect(dsl.data).to
|
33
|
+
expect(dsl.data).to eq("BODY")
|
34
34
|
end
|
35
35
|
|
36
36
|
it "returns hash" do
|
@@ -5,7 +5,7 @@ describe Aitch::Namespace do
|
|
5
5
|
ns = Aitch::Namespace.new
|
6
6
|
ns.config.user_agent = "MyLib/1.0.0"
|
7
7
|
|
8
|
-
expect(ns.config.user_agent).to
|
8
|
+
expect(ns.config.user_agent).to eq("MyLib/1.0.0")
|
9
9
|
expect(Aitch.config.user_agent).to match(%r[^Aitch])
|
10
10
|
end
|
11
11
|
end
|
data/spec/aitch/request_spec.rb
CHANGED
@@ -38,30 +38,38 @@ describe Aitch::Request do
|
|
38
38
|
}.to raise_error(Aitch::RequestTimeoutError)
|
39
39
|
end
|
40
40
|
|
41
|
+
it "raises exception for invalid http method" do
|
42
|
+
request = build_request(request_method: "invalid", url: "http://example.org")
|
43
|
+
|
44
|
+
expect {
|
45
|
+
request.perform
|
46
|
+
}.to raise_error(Aitch::InvalidHTTPMethodError)
|
47
|
+
end
|
48
|
+
|
41
49
|
it "sets user agent" do
|
42
50
|
requester = build_request
|
43
51
|
request = requester.request
|
44
|
-
expect(request["User-Agent"]).to
|
52
|
+
expect(request["User-Agent"]).to eq(requester.options[:user_agent])
|
45
53
|
end
|
46
54
|
|
47
55
|
it "requests gzip encoding" do
|
48
56
|
request = build_request.request
|
49
|
-
expect(request["Accept-Encoding"]).to
|
57
|
+
expect(request["Accept-Encoding"]).to eq("gzip,deflate")
|
50
58
|
end
|
51
59
|
|
52
60
|
it "sets path" do
|
53
61
|
request = build_request(url: "http://example.org/some/path").request
|
54
|
-
expect(request.path).to
|
62
|
+
expect(request.path).to eq("/some/path")
|
55
63
|
end
|
56
64
|
|
57
65
|
it "sets request body from hash" do
|
58
66
|
request = build_request(request_method: "post", data: {a: 1}).request
|
59
|
-
expect(request.body).to
|
67
|
+
expect(request.body).to eq("a=1")
|
60
68
|
end
|
61
69
|
|
62
70
|
it "sets request body from string" do
|
63
71
|
request = build_request(request_method: "post", data: "some body").request
|
64
|
-
expect(request.body).to
|
72
|
+
expect(request.body).to eq("some body")
|
65
73
|
end
|
66
74
|
|
67
75
|
it "sets json body from object" do
|
@@ -72,7 +80,7 @@ describe Aitch::Request do
|
|
72
80
|
options: {json_parser: JSON}
|
73
81
|
).request
|
74
82
|
|
75
|
-
expect(request.body).to
|
83
|
+
expect(request.body).to eq({a: 1}.to_json)
|
76
84
|
end
|
77
85
|
|
78
86
|
it "sets json body from object (default headers)" do
|
@@ -82,27 +90,27 @@ describe Aitch::Request do
|
|
82
90
|
options: {json_parser: JSON, default_headers: {'Content-Type' => 'application/json'}}
|
83
91
|
).request
|
84
92
|
|
85
|
-
expect(request.body).to
|
93
|
+
expect(request.body).to eq({a: 1}.to_json)
|
86
94
|
end
|
87
95
|
|
88
96
|
it "sets request body from to_h protocol" do
|
89
97
|
data = double(to_h: {a: 1})
|
90
98
|
request = build_request(request_method: "post", data: data).request
|
91
|
-
expect(request.body).to
|
99
|
+
expect(request.body).to eq("a=1")
|
92
100
|
end
|
93
101
|
|
94
102
|
it "sets request body from to_s protocol" do
|
95
103
|
data = double(to_s: "some body")
|
96
104
|
request = build_request(request_method: "post", data: data).request
|
97
105
|
|
98
|
-
expect(request.body).to
|
106
|
+
expect(request.body).to eq("some body")
|
99
107
|
end
|
100
108
|
|
101
109
|
it "sets query string from hash data" do
|
102
|
-
|
110
|
+
register_uri :get, "http://example.org/?a=1&b=2", body: "hello"
|
103
111
|
requester = build_request(data: {a: 1, b: 2})
|
104
112
|
|
105
|
-
expect(requester.perform.body).to
|
113
|
+
expect(requester.perform.body).to eq("hello")
|
106
114
|
end
|
107
115
|
|
108
116
|
it "sets default headers" do
|
@@ -110,24 +118,24 @@ describe Aitch::Request do
|
|
110
118
|
requester.options[:default_headers] = {"HEADER" => "VALUE"}
|
111
119
|
request = requester.request
|
112
120
|
|
113
|
-
expect(request["HEADER"]).to
|
121
|
+
expect(request["HEADER"]).to eq("VALUE")
|
114
122
|
end
|
115
123
|
|
116
124
|
it "sets custom headers" do
|
117
125
|
request = build_request(headers: {"HEADER" => "VALUE"}).request
|
118
|
-
expect(request["HEADER"]).to
|
126
|
+
expect(request["HEADER"]).to eq("VALUE")
|
119
127
|
end
|
120
128
|
|
121
129
|
it "executes headers with callable protocol" do
|
122
130
|
request = build_request(headers: {"HEADER" => -> { "VALUE" }}).request
|
123
|
-
expect(request["HEADER"]).to
|
131
|
+
expect(request["HEADER"]).to eq("VALUE")
|
124
132
|
end
|
125
133
|
|
126
134
|
it "sets basic auth credentials" do
|
127
135
|
request = build_request(options: {user: "USER", password: "PASS"}).request
|
128
136
|
credentials = Base64.decode64(request["Authorization"].gsub(/Basic /, ""))
|
129
137
|
|
130
|
-
expect(credentials).to
|
138
|
+
expect(credentials).to eq("USER:PASS")
|
131
139
|
end
|
132
140
|
|
133
141
|
describe "#client" do
|
@@ -140,12 +148,12 @@ describe Aitch::Request do
|
|
140
148
|
end
|
141
149
|
|
142
150
|
it "sets verification mode" do
|
143
|
-
expect(client.verify_mode).to
|
151
|
+
expect(client.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
144
152
|
end
|
145
153
|
|
146
154
|
it "sets timeout" do
|
147
155
|
request.options[:timeout] = 20
|
148
|
-
expect(client.read_timeout).to
|
156
|
+
expect(client.read_timeout).to eq(20)
|
149
157
|
end
|
150
158
|
end
|
151
159
|
end
|
@@ -169,7 +177,7 @@ describe Aitch::Request do
|
|
169
177
|
].each do |method|
|
170
178
|
it "instantiates #{method.upcase} method" do
|
171
179
|
request = build_request(request_method: method).request
|
172
|
-
expect(request.class.name).to
|
180
|
+
expect(request.class.name).to eq("Net::HTTP::#{method.capitalize}")
|
173
181
|
end
|
174
182
|
end
|
175
183
|
end
|
@@ -180,23 +188,23 @@ describe Aitch::Request do
|
|
180
188
|
it "follows redirect" do
|
181
189
|
Aitch.configuration.redirect_limit = 5
|
182
190
|
|
183
|
-
|
184
|
-
|
185
|
-
|
191
|
+
register_uri(:get, "http://example.org/", location: "http://example.com/", status: 301)
|
192
|
+
register_uri(:get, "http://example.com/", location: "http://www.example.com/", status: 301)
|
193
|
+
register_uri(:get, "http://www.example.com/", body: "Hello")
|
186
194
|
|
187
195
|
response = Aitch.get("http://example.org/")
|
188
196
|
|
189
197
|
expect(response).not_to be_redirect
|
190
|
-
expect(response.body).to
|
191
|
-
expect(response.redirected_from).to
|
192
|
-
expect(response.url).to
|
198
|
+
expect(response.body).to eq("Hello")
|
199
|
+
expect(response.redirected_from).to eq(["http://example.org/", "http://example.com/"])
|
200
|
+
expect(response.url).to eq("http://www.example.com/")
|
193
201
|
end
|
194
202
|
|
195
203
|
it "raises when doing too many redirects" do
|
196
204
|
Aitch.configuration.redirect_limit = 1
|
197
205
|
|
198
|
-
|
199
|
-
|
206
|
+
register_uri(:get, "http://example.org/", location: "http://example.com/", status: 301)
|
207
|
+
register_uri(:get, "http://example.com/", location: "https://example.com/", status: 301)
|
200
208
|
|
201
209
|
expect {
|
202
210
|
Aitch.get("http://example.org/")
|
@@ -206,16 +214,16 @@ describe Aitch::Request do
|
|
206
214
|
|
207
215
|
describe "GET requests" do
|
208
216
|
it "sets data as query string" do
|
209
|
-
|
217
|
+
register_uri(:get, /.+/)
|
210
218
|
Aitch.get("http://example.org/", a: 1, b: 2)
|
211
219
|
|
212
|
-
expect(
|
220
|
+
expect(last_request.uri.request_uri).to eq("/?a=1&b=2")
|
213
221
|
end
|
214
222
|
end
|
215
223
|
|
216
224
|
describe "using the DSL" do
|
217
225
|
it "performs request" do
|
218
|
-
|
226
|
+
register_uri(:post, /.+/)
|
219
227
|
|
220
228
|
response = Aitch.post do
|
221
229
|
url "http://example.org/some/path"
|
@@ -224,13 +232,30 @@ describe Aitch::Request do
|
|
224
232
|
options user: "user", password: "pass"
|
225
233
|
end
|
226
234
|
|
227
|
-
expect(
|
228
|
-
expect(
|
229
|
-
expect(
|
230
|
-
expect(
|
235
|
+
expect(last_request.uri.request_uri).to eq("/some/path")
|
236
|
+
expect(last_request.method).to eq(:post)
|
237
|
+
expect(last_request.body).to eq("a=1&b=2")
|
238
|
+
expect(last_request.headers["Rendering"]).to eq("0.1")
|
239
|
+
expect(last_request.uri.user).to eq("user")
|
240
|
+
expect(last_request.uri.password).to eq("pass")
|
241
|
+
end
|
242
|
+
end
|
231
243
|
|
232
|
-
|
233
|
-
|
244
|
+
describe "status code validation" do
|
245
|
+
it "raises exception when status code isn't valid" do
|
246
|
+
register_uri(:get, "http://example.org/", status: 404)
|
247
|
+
|
248
|
+
expect {
|
249
|
+
Aitch.get("http://example.org/", {}, {}, expect: [200])
|
250
|
+
}.to raise_error(Aitch::StatusCodeError, "Expected(200 OK) <=> Actual(404 Not Found)")
|
251
|
+
end
|
252
|
+
|
253
|
+
it "accepts valid status code" do
|
254
|
+
register_uri(:get, "http://example.org/", status: 200)
|
255
|
+
|
256
|
+
expect {
|
257
|
+
Aitch.get("http://example.org/", {}, {}, expect: [200])
|
258
|
+
}.not_to raise_error
|
234
259
|
end
|
235
260
|
end
|
236
261
|
end
|
data/spec/aitch/response_spec.rb
CHANGED
@@ -2,15 +2,15 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Aitch::Response do
|
4
4
|
it "has body" do
|
5
|
-
|
5
|
+
register_uri(:get, "http://example.org/", body: "Hello")
|
6
6
|
response = Aitch.get("http://example.org/")
|
7
|
-
expect(response.body).to
|
7
|
+
expect(response.body).to eq("Hello")
|
8
8
|
end
|
9
9
|
|
10
10
|
it "sets current url" do
|
11
|
-
|
11
|
+
register_uri(:get, "http://example.org/", body: "Hello")
|
12
12
|
response = Aitch.get("http://example.org/")
|
13
|
-
expect(response.url).to
|
13
|
+
expect(response.url).to eq("http://example.org/")
|
14
14
|
end
|
15
15
|
|
16
16
|
it "parses gzip response" do
|
@@ -19,74 +19,111 @@ describe Aitch::Response do
|
|
19
19
|
gzipped.write("Hello")
|
20
20
|
gzipped.finish
|
21
21
|
|
22
|
-
|
22
|
+
register_uri(:get, "http://example.org/", body: stdio.string, content_encoding: "gzip")
|
23
23
|
response = Aitch.get("http://example.org/")
|
24
24
|
|
25
|
-
expect(response.body).to
|
25
|
+
expect(response.body).to eq("Hello")
|
26
26
|
end
|
27
27
|
|
28
28
|
it "deflates response" do
|
29
29
|
stdio = StringIO.new
|
30
30
|
deflated = Zlib::Deflate.deflate("Hello")
|
31
31
|
|
32
|
-
|
32
|
+
register_uri(:get, "http://example.org/", body: deflated, content_encoding: "deflate")
|
33
33
|
response = Aitch.get("http://example.org/")
|
34
34
|
|
35
|
-
expect(response.body).to
|
35
|
+
expect(response.body).to eq("Hello")
|
36
36
|
end
|
37
37
|
|
38
38
|
it "returns status code" do
|
39
|
-
|
39
|
+
register_uri(:get, "http://example.org/", body: "")
|
40
40
|
response = Aitch.get("http://example.org/")
|
41
|
-
expect(response.code).to
|
41
|
+
expect(response.code).to eq(200)
|
42
42
|
end
|
43
43
|
|
44
44
|
it "returns content type" do
|
45
|
-
|
45
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
46
46
|
response = Aitch.get("http://example.org/")
|
47
|
-
expect(response.content_type).to
|
47
|
+
expect(response.content_type).to eq("text/html")
|
48
48
|
end
|
49
49
|
|
50
50
|
it "detects as successful response" do
|
51
|
-
|
51
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
52
52
|
response = Aitch.get("http://example.org/")
|
53
53
|
expect(response).to be_success
|
54
54
|
end
|
55
55
|
|
56
56
|
it "returns headers" do
|
57
|
-
|
57
|
+
register_uri(:get, "http://example.org/", content_type: "text/html")
|
58
58
|
headers = Aitch.get("http://example.org/").headers
|
59
59
|
|
60
60
|
expect(headers).to be_a(Hash)
|
61
|
-
expect(headers["content-type"]).to
|
61
|
+
expect(headers["content-type"]).to eq("text/html")
|
62
62
|
end
|
63
63
|
|
64
64
|
it "normalizes custom headers" do
|
65
|
-
|
65
|
+
register_uri(:get, "http://example.org/", headers: {"X-Runtime" => "0.003"})
|
66
66
|
headers = Aitch.get("http://example.org/").headers
|
67
67
|
|
68
|
-
expect(headers["runtime"]).to
|
68
|
+
expect(headers["runtime"]).to eq("0.003")
|
69
69
|
end
|
70
70
|
|
71
71
|
it "maps missing methods to headers" do
|
72
|
-
|
72
|
+
register_uri(:get, "http://example.org/", headers: {"X-Runtime" => "0.003"})
|
73
73
|
response = Aitch.get("http://example.org/")
|
74
74
|
|
75
|
-
expect(response.runtime).to
|
75
|
+
expect(response.runtime).to eq("0.003")
|
76
76
|
expect(response).to respond_to(:runtime)
|
77
77
|
end
|
78
78
|
|
79
|
+
it "raises when have no method" do
|
80
|
+
register_uri(:get, "http://example.org/")
|
81
|
+
response = Aitch.get("http://example.org/")
|
82
|
+
|
83
|
+
expect {
|
84
|
+
response.runtime
|
85
|
+
}.to raise_error(NoMethodError)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns description for 200 OK" do
|
89
|
+
register_uri(:get, "http://example.org/", status: 200)
|
90
|
+
response = Aitch.get("http://example.org/")
|
91
|
+
|
92
|
+
expect(response.description).to eq("200 OK")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns description for 101 Switch Protocol" do
|
96
|
+
register_uri(:get, "http://example.org/", status: 101)
|
97
|
+
response = Aitch.get("http://example.org/")
|
98
|
+
|
99
|
+
expect(response.description).to eq("101 Switch Protocol")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns description for 444 No Response (nginx)" do
|
103
|
+
register_uri(:get, "http://example.org/", status: 444)
|
104
|
+
response = Aitch.get("http://example.org/")
|
105
|
+
|
106
|
+
expect(response.description).to eq("444")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "overrides inspect" do
|
110
|
+
register_uri(:get, "http://example.org/", status: 101, content_type: "text/html")
|
111
|
+
response = Aitch.get("http://example.org/")
|
112
|
+
|
113
|
+
expect(response.inspect).to eq("#<Aitch::Response 101 Switch Protocol (text/html)>")
|
114
|
+
end
|
115
|
+
|
79
116
|
context "status 3xx" do
|
80
117
|
before { Aitch.configuration.follow_redirect = false }
|
81
118
|
|
82
119
|
it "has body" do
|
83
|
-
|
120
|
+
register_uri(:get, "http://example.org/", body: "Hello", status: 301)
|
84
121
|
response = Aitch.get("http://example.org/")
|
85
|
-
expect(response.body).to
|
122
|
+
expect(response.body).to eq("Hello")
|
86
123
|
end
|
87
124
|
|
88
125
|
it "detects as successful response" do
|
89
|
-
|
126
|
+
register_uri(:get, "http://example.org/", status: 301)
|
90
127
|
response = Aitch.get("http://example.org/")
|
91
128
|
|
92
129
|
expect(response).to be_success
|
@@ -94,91 +131,99 @@ describe Aitch::Response do
|
|
94
131
|
end
|
95
132
|
|
96
133
|
it "detects as redirect" do
|
97
|
-
|
134
|
+
register_uri(:get, "http://example.org/", status: 301)
|
98
135
|
response = Aitch.get("http://example.org/")
|
99
136
|
expect(response).to be_redirect
|
100
137
|
end
|
101
138
|
|
102
139
|
it "returns location" do
|
103
|
-
|
140
|
+
register_uri(:get, "http://example.org/", status: 301, location: "https://example.com/")
|
104
141
|
response = Aitch.get("http://example.org/")
|
105
|
-
expect(response.location).to
|
142
|
+
expect(response.location).to eq("https://example.com/")
|
106
143
|
end
|
107
144
|
|
108
145
|
it "follows absolute paths" do
|
109
146
|
Aitch.configuration.follow_redirect = true
|
110
147
|
Aitch.configuration.redirect_limit = 5
|
111
148
|
|
112
|
-
|
113
|
-
|
114
|
-
|
149
|
+
register_uri(:get, "http://example.org/", status: 301, location: "/hello")
|
150
|
+
register_uri(:get, "http://example.org/hello", status: 301, location: "/hi")
|
151
|
+
register_uri(:get, "http://example.org/hi", status: 200, body: "Hi")
|
115
152
|
|
116
153
|
response = Aitch.get("http://example.org/")
|
117
154
|
|
118
|
-
expect(response.redirected_from).to
|
119
|
-
expect(response.url).to
|
120
|
-
expect(response.body).to
|
155
|
+
expect(response.redirected_from).to eq(["http://example.org/", "http://example.org/hello"])
|
156
|
+
expect(response.url).to eq("http://example.org/hi")
|
157
|
+
expect(response.body).to eq("Hi")
|
121
158
|
end
|
122
159
|
end
|
123
160
|
|
124
161
|
context "status 4xx" do
|
125
162
|
it "detects as error" do
|
126
|
-
|
163
|
+
register_uri(:get, "http://example.org/", status: 404)
|
127
164
|
response = Aitch.get("http://example.org/")
|
128
165
|
|
129
166
|
expect(response).to be_error
|
130
167
|
end
|
131
168
|
|
132
169
|
it "sets error" do
|
133
|
-
|
170
|
+
register_uri(:get, "http://example.org/", status: 404)
|
134
171
|
response = Aitch.get("http://example.org/")
|
135
172
|
|
136
|
-
expect(response.error).to
|
173
|
+
expect(response.error).to eq(Aitch::NotFoundError)
|
137
174
|
end
|
138
175
|
end
|
139
176
|
|
140
177
|
context "status 5xx" do
|
141
178
|
it "detects as error" do
|
142
|
-
|
179
|
+
register_uri(:get, "http://example.org/", status: 500)
|
143
180
|
response = Aitch.get("http://example.org/")
|
144
181
|
|
145
182
|
expect(response).to be_error
|
146
183
|
end
|
147
184
|
|
148
185
|
it "sets error" do
|
149
|
-
|
186
|
+
register_uri(:get, "http://example.org/", status: 500)
|
150
187
|
response = Aitch.get("http://example.org/")
|
151
188
|
|
152
|
-
expect(response.error).to
|
189
|
+
expect(response.error).to eq(Aitch::InternalServerErrorError)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "raw body" do
|
194
|
+
it "returns as it is" do
|
195
|
+
register_uri(:get, "http://example.org/", body: "HELLO", content_type: "text/plain")
|
196
|
+
response = Aitch.get("http://example.org/")
|
197
|
+
expect(response.body).to eq("HELLO")
|
153
198
|
end
|
154
199
|
end
|
155
200
|
|
156
201
|
context "JSON" do
|
157
202
|
it "detects as json" do
|
158
|
-
|
203
|
+
register_uri(:get, "http://example.org/", body: "[]", content_type: "application/json")
|
159
204
|
response = Aitch.get("http://example.org/")
|
160
205
|
|
161
206
|
expect(response).to be_json
|
162
207
|
end
|
163
208
|
|
164
209
|
it "returns json" do
|
165
|
-
|
210
|
+
register_uri(:get, "http://example.org/", body: "[1,2,3]", content_type: "application/json")
|
166
211
|
response = Aitch.get("http://example.org/")
|
167
212
|
|
168
|
-
expect(response.json).to
|
213
|
+
expect(response.json).to eq([1,2,3])
|
169
214
|
end
|
170
215
|
end
|
171
216
|
|
172
217
|
context "HTML" do
|
173
218
|
it "detects as html" do
|
174
|
-
|
219
|
+
register_uri(:get, "http://example.org/", body: "", content_type: "text/html")
|
175
220
|
response = Aitch.get("http://example.org/")
|
176
221
|
|
177
222
|
expect(response).to be_html
|
178
223
|
end
|
179
224
|
|
180
225
|
it "returns html" do
|
181
|
-
|
226
|
+
register_uri(:get, "http://example.org/", body: "Hello", content_type: "text/html")
|
182
227
|
response = Aitch.get("http://example.org/")
|
183
228
|
|
184
229
|
expect(response.html).to be_a(Nokogiri::HTML::Document)
|
@@ -187,14 +232,14 @@ describe Aitch::Response do
|
|
187
232
|
|
188
233
|
context "XML" do
|
189
234
|
it "detects as xml" do
|
190
|
-
|
235
|
+
register_uri(:get, "http://example.org/", body: "[]", content_type: "application/xml")
|
191
236
|
response = Aitch.get("http://example.org/")
|
192
237
|
|
193
238
|
expect(response).to be_xml
|
194
239
|
end
|
195
240
|
|
196
241
|
it "returns xml" do
|
197
|
-
|
242
|
+
register_uri(:get, "http://example.org/", body: "<foo/>", content_type: "application/xml")
|
198
243
|
response = Aitch.get("http://example.org/")
|
199
244
|
|
200
245
|
expect(response.xml).to be_a(Nokogiri::XML::Document)
|
data/spec/aitch/uri_spec.rb
CHANGED
@@ -2,35 +2,35 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Aitch::URI do
|
4
4
|
it "returns default path" do
|
5
|
-
expect(Aitch::URI.new("http://example.org").path).to
|
5
|
+
expect(Aitch::URI.new("http://example.org").path).to eq("/")
|
6
6
|
end
|
7
7
|
|
8
8
|
it "returns defined path" do
|
9
|
-
expect(Aitch::URI.new("http://example.org/some/path").path).to
|
9
|
+
expect(Aitch::URI.new("http://example.org/some/path").path).to eq("/some/path")
|
10
10
|
end
|
11
11
|
|
12
12
|
it "returns fragment" do
|
13
|
-
expect(Aitch::URI.new("http://example.org/#top").fragment).to
|
13
|
+
expect(Aitch::URI.new("http://example.org/#top").fragment).to eq("#top")
|
14
14
|
end
|
15
15
|
|
16
16
|
it "returns query string" do
|
17
|
-
expect(Aitch::URI.new("http://example.org/?a=1&b=2").query).to
|
17
|
+
expect(Aitch::URI.new("http://example.org/?a=1&b=2").query).to eq("?a=1&b=2")
|
18
18
|
end
|
19
19
|
|
20
20
|
it "converts data into query string" do
|
21
|
-
expect(Aitch::URI.new("http://example.org", a: 1, b: 2).query).to
|
21
|
+
expect(Aitch::URI.new("http://example.org", a: 1, b: 2).query).to eq("?a=1&b=2")
|
22
22
|
end
|
23
23
|
|
24
24
|
it "merges data into query string" do
|
25
|
-
expect(Aitch::URI.new("http://example.org/?a=1&b=2", c: 3).query).to
|
25
|
+
expect(Aitch::URI.new("http://example.org/?a=1&b=2", c: 3).query).to eq("?a=1&b=2&c=3")
|
26
26
|
end
|
27
27
|
|
28
28
|
it "ignores data when request has body" do
|
29
|
-
expect(Aitch::URI.new("http://example.org/", {c: 3}, true).query).to
|
29
|
+
expect(Aitch::URI.new("http://example.org/", {c: 3}, true).query).to eq(nil)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "returns request uri" do
|
33
33
|
uri = Aitch::URI.new("http://example.org/some/path?a=1&b=2#hello", c: 3)
|
34
|
-
expect(uri.request_uri).to
|
34
|
+
expect(uri.request_uri).to eq("/some/path?a=1&b=2&c=3#hello")
|
35
35
|
end
|
36
36
|
end
|
data/spec/aitch/utils_spec.rb
CHANGED
@@ -3,17 +3,17 @@ require "spec_helper"
|
|
3
3
|
describe Aitch::Utils do
|
4
4
|
describe ".underscore" do
|
5
5
|
it "replaces capital letters by underscores" do
|
6
|
-
expect(Aitch::Utils.underscore("SomeConstantName")).to
|
6
|
+
expect(Aitch::Utils.underscore("SomeConstantName")).to eq("some_constant_name")
|
7
7
|
end
|
8
8
|
|
9
9
|
it "considers URI acronym" do
|
10
|
-
expect(Aitch::Utils.underscore("RequestURITooLong")).to
|
10
|
+
expect(Aitch::Utils.underscore("RequestURITooLong")).to eq("request_uri_too_long")
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
describe ".symbolize_keys" do
|
15
15
|
it "converts keys to symbols" do
|
16
|
-
expect(Aitch::Utils.symbolize_keys("a" => 1)).to
|
16
|
+
expect(Aitch::Utils.symbolize_keys("a" => 1)).to eq(a: 1)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -10,7 +10,7 @@ describe Aitch::XMLParser do
|
|
10
10
|
it "converts ISO-8859-1 to UTF-8" do
|
11
11
|
xml = Aitch::XMLParser.load(File.read("./spec/fixtures/iso8859-1.xml"))
|
12
12
|
|
13
|
-
expect(xml.encoding).to
|
13
|
+
expect(xml.encoding).to eq("utf-8")
|
14
14
|
expect(xml.to_xml).to include(%[<?xml version="1.0" encoding="utf-8"?>])
|
15
15
|
end
|
16
16
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
1
4
|
require "bundler/setup"
|
2
5
|
Bundler.require
|
3
6
|
|
4
7
|
require "aitch"
|
5
8
|
require "base64"
|
6
9
|
require "test_notifier/runner/rspec"
|
7
|
-
require "
|
10
|
+
require "webmock/rspec"
|
8
11
|
require "nokogiri"
|
9
12
|
|
10
|
-
|
13
|
+
require_relative "support/webmock"
|
14
|
+
require_relative "support/request_uri"
|
11
15
|
|
12
16
|
RSpec.configure do |config|
|
13
17
|
config.filter_run_excluding :ruby => -> version {
|
@@ -0,0 +1,24 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.include Module.new {
|
3
|
+
def add_hash_entry(source, target, from, to)
|
4
|
+
target[to] = source[from] if source[from]
|
5
|
+
end
|
6
|
+
|
7
|
+
def register_uri(http_method, url, options = {})
|
8
|
+
body = options.fetch(:body, '')
|
9
|
+
status = options.fetch(:status, 200)
|
10
|
+
headers = options.fetch(:headers, {})
|
11
|
+
|
12
|
+
add_hash_entry(options, headers, :location, 'Location')
|
13
|
+
add_hash_entry(options, headers, :content_type, 'Content-Type')
|
14
|
+
add_hash_entry(options, headers, :content_encoding, 'Content-Encoding')
|
15
|
+
|
16
|
+
stub_request(http_method, url)
|
17
|
+
.to_return(status: status, body: body, headers: headers)
|
18
|
+
end
|
19
|
+
|
20
|
+
def last_request
|
21
|
+
WebMock.requests.last
|
22
|
+
end
|
23
|
+
}
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
WebMock.disable_net_connect!(allow: /codeclimate\.com/)
|
2
|
+
|
3
|
+
def WebMock.requests
|
4
|
+
@requests ||= []
|
5
|
+
end
|
6
|
+
|
7
|
+
WebMock.after_request do |request, response|
|
8
|
+
WebMock.requests << request
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.before(:each) do
|
13
|
+
WebMock.requests.clear
|
14
|
+
end
|
15
|
+
end
|
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: 0.
|
4
|
+
version: 0.5.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:
|
11
|
+
date: 2015-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -25,13 +25,13 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.6.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: codeclimate-test-reporter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
|
-
type: :
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: webmock
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -115,12 +115,10 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
-
- ".coveralls.yml"
|
119
118
|
- ".gitignore"
|
120
119
|
- ".rspec"
|
121
120
|
- ".travis.yml"
|
122
121
|
- Gemfile
|
123
|
-
- Gemfile.lock
|
124
122
|
- LICENSE.txt
|
125
123
|
- README.md
|
126
124
|
- Rakefile
|
@@ -129,6 +127,7 @@ files:
|
|
129
127
|
- lib/aitch/configuration.rb
|
130
128
|
- lib/aitch/dsl.rb
|
131
129
|
- lib/aitch/errors.rb
|
130
|
+
- lib/aitch/ext/to_query.rb
|
132
131
|
- lib/aitch/html_parser.rb
|
133
132
|
- lib/aitch/location.rb
|
134
133
|
- lib/aitch/namespace.rb
|
@@ -136,6 +135,7 @@ files:
|
|
136
135
|
- lib/aitch/request.rb
|
137
136
|
- lib/aitch/response.rb
|
138
137
|
- lib/aitch/response/body.rb
|
138
|
+
- lib/aitch/response/description.rb
|
139
139
|
- lib/aitch/response/errors.rb
|
140
140
|
- lib/aitch/uri.rb
|
141
141
|
- lib/aitch/utils.rb
|
@@ -153,6 +153,8 @@ files:
|
|
153
153
|
- spec/aitch/xml_parser_spec.rb
|
154
154
|
- spec/fixtures/iso8859-1.xml
|
155
155
|
- spec/spec_helper.rb
|
156
|
+
- spec/support/request_uri.rb
|
157
|
+
- spec/support/webmock.rb
|
156
158
|
homepage: http://rubygems.org/gems/aitch
|
157
159
|
licenses:
|
158
160
|
- MIT
|
@@ -173,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
175
|
version: '0'
|
174
176
|
requirements: []
|
175
177
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.
|
178
|
+
rubygems_version: 2.4.6
|
177
179
|
signing_key:
|
178
180
|
specification_version: 4
|
179
181
|
summary: A simple HTTP client
|
@@ -190,3 +192,5 @@ test_files:
|
|
190
192
|
- spec/aitch/xml_parser_spec.rb
|
191
193
|
- spec/fixtures/iso8859-1.xml
|
192
194
|
- spec/spec_helper.rb
|
195
|
+
- spec/support/request_uri.rb
|
196
|
+
- spec/support/webmock.rb
|
data/.coveralls.yml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
service_name: travis-ci
|