http 0.7.4 → 0.8.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +5 -2
  4. data/CHANGES.md +24 -7
  5. data/CONTRIBUTING.md +25 -0
  6. data/Gemfile +24 -22
  7. data/Guardfile +2 -2
  8. data/README.md +34 -4
  9. data/Rakefile +7 -7
  10. data/examples/parallel_requests_with_celluloid.rb +2 -2
  11. data/http.gemspec +12 -12
  12. data/lib/http.rb +11 -10
  13. data/lib/http/cache.rb +146 -0
  14. data/lib/http/cache/headers.rb +100 -0
  15. data/lib/http/cache/null_cache.rb +13 -0
  16. data/lib/http/chainable.rb +14 -3
  17. data/lib/http/client.rb +64 -80
  18. data/lib/http/connection.rb +139 -0
  19. data/lib/http/content_type.rb +2 -2
  20. data/lib/http/errors.rb +7 -1
  21. data/lib/http/headers.rb +21 -8
  22. data/lib/http/headers/mixin.rb +1 -1
  23. data/lib/http/mime_type.rb +2 -2
  24. data/lib/http/mime_type/adapter.rb +2 -2
  25. data/lib/http/mime_type/json.rb +4 -4
  26. data/lib/http/options.rb +65 -74
  27. data/lib/http/redirector.rb +3 -3
  28. data/lib/http/request.rb +20 -13
  29. data/lib/http/request/caching.rb +95 -0
  30. data/lib/http/request/writer.rb +5 -5
  31. data/lib/http/response.rb +15 -9
  32. data/lib/http/response/body.rb +21 -8
  33. data/lib/http/response/caching.rb +142 -0
  34. data/lib/http/response/io_body.rb +63 -0
  35. data/lib/http/response/parser.rb +1 -1
  36. data/lib/http/response/status.rb +4 -12
  37. data/lib/http/response/status/reasons.rb +53 -53
  38. data/lib/http/response/string_body.rb +53 -0
  39. data/lib/http/version.rb +1 -1
  40. data/spec/lib/http/cache/headers_spec.rb +77 -0
  41. data/spec/lib/http/cache_spec.rb +182 -0
  42. data/spec/lib/http/client_spec.rb +123 -95
  43. data/spec/lib/http/content_type_spec.rb +25 -25
  44. data/spec/lib/http/headers/mixin_spec.rb +8 -8
  45. data/spec/lib/http/headers_spec.rb +213 -173
  46. data/spec/lib/http/options/body_spec.rb +5 -5
  47. data/spec/lib/http/options/form_spec.rb +3 -3
  48. data/spec/lib/http/options/headers_spec.rb +7 -7
  49. data/spec/lib/http/options/json_spec.rb +3 -3
  50. data/spec/lib/http/options/merge_spec.rb +26 -22
  51. data/spec/lib/http/options/new_spec.rb +10 -10
  52. data/spec/lib/http/options/proxy_spec.rb +8 -8
  53. data/spec/lib/http/options_spec.rb +2 -2
  54. data/spec/lib/http/redirector_spec.rb +32 -32
  55. data/spec/lib/http/request/caching_spec.rb +133 -0
  56. data/spec/lib/http/request/writer_spec.rb +26 -26
  57. data/spec/lib/http/request_spec.rb +63 -58
  58. data/spec/lib/http/response/body_spec.rb +13 -13
  59. data/spec/lib/http/response/caching_spec.rb +201 -0
  60. data/spec/lib/http/response/io_body_spec.rb +35 -0
  61. data/spec/lib/http/response/status_spec.rb +25 -25
  62. data/spec/lib/http/response/string_body_spec.rb +35 -0
  63. data/spec/lib/http/response_spec.rb +64 -45
  64. data/spec/lib/http_spec.rb +103 -76
  65. data/spec/spec_helper.rb +10 -12
  66. data/spec/support/connection_reuse_shared.rb +100 -0
  67. data/spec/support/create_certs.rb +12 -12
  68. data/spec/support/dummy_server.rb +11 -11
  69. data/spec/support/dummy_server/servlet.rb +43 -31
  70. data/spec/support/proxy_server.rb +31 -25
  71. metadata +57 -8
  72. data/spec/support/example_server.rb +0 -30
  73. data/spec/support/example_server/servlet.rb +0 -102
@@ -0,0 +1,35 @@
1
+ RSpec.describe HTTP::Response::IoBody do
2
+ subject(:body) { described_class.new StringIO.new("Hello, World!") }
3
+
4
+ it "has the content" do
5
+ expect(subject.to_s).to eq "Hello, World!"
6
+ end
7
+
8
+ context "when body empty" do
9
+ subject(:body) { described_class.new StringIO.new("") }
10
+
11
+ it "returns responds to empty? with true" do
12
+ expect(subject).to be_empty
13
+ end
14
+ end
15
+
16
+ describe "#readpartial" do
17
+ context "with size given" do
18
+ it "returns only that amount" do
19
+ expect(body.readpartial(4)).to eq "Hell"
20
+ end
21
+ end
22
+
23
+ context "without size given" do
24
+ it "returns parts of the content" do
25
+ expect(body.readpartial).to eq "Hello, World!"
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#each" do
31
+ it "yields successive parts of the content" do
32
+ expect { |b| body.each(&b) }.to yield_with_args "Hello, World!"
33
+ end
34
+ end
35
+ end
@@ -1,24 +1,24 @@
1
1
  RSpec.describe HTTP::Response::Status do
2
- describe '.new' do
3
- it 'fails if given value does not respond to #to_i' do
2
+ describe ".new" do
3
+ it "fails if given value does not respond to #to_i" do
4
4
  expect { described_class.new double }.to raise_error
5
5
  end
6
6
 
7
- it 'accepts any object that responds to #to_i' do
7
+ it "accepts any object that responds to #to_i" do
8
8
  expect { described_class.new double :to_i => 200 }.to_not raise_error
9
9
  end
10
10
  end
11
11
 
12
- describe '#code' do
13
- subject { described_class.new('200.0').code }
12
+ describe "#code" do
13
+ subject { described_class.new("200.0").code }
14
14
  it { is_expected.to eq 200 }
15
15
  it { is_expected.to be_a Fixnum }
16
16
  end
17
17
 
18
- describe '#reason' do
18
+ describe "#reason" do
19
19
  subject { described_class.new(code).reason }
20
20
 
21
- context 'with unknown code' do
21
+ context "with unknown code" do
22
22
  let(:code) { 1024 }
23
23
  it { is_expected.to be_nil }
24
24
  end
@@ -34,10 +34,10 @@ RSpec.describe HTTP::Response::Status do
34
34
  end
35
35
  end
36
36
 
37
- describe '#symbolize' do
37
+ describe "#symbolize" do
38
38
  subject { described_class.new(code).symbolize }
39
39
 
40
- context 'with unknown code' do
40
+ context "with unknown code" do
41
41
  let(:code) { 1024 }
42
42
  it { is_expected.to be_nil }
43
43
  end
@@ -52,15 +52,15 @@ RSpec.describe HTTP::Response::Status do
52
52
  end
53
53
  end
54
54
 
55
- describe '#inspect' do
56
- it 'returns quoted code and reason phrase' do
55
+ describe "#inspect" do
56
+ it "returns quoted code and reason phrase" do
57
57
  status = described_class.new 200
58
58
  expect(status.inspect).to eq '"200 OK"'
59
59
  end
60
60
  end
61
61
 
62
62
  # testing edge cases only
63
- describe '::SYMBOLS' do
63
+ describe "::SYMBOLS" do
64
64
  subject { described_class::SYMBOLS }
65
65
 
66
66
  # "OK"
@@ -99,38 +99,38 @@ RSpec.describe HTTP::Response::Status do
99
99
  RUBY
100
100
  end
101
101
 
102
- describe '.coerce' do
103
- context 'with String' do
104
- it 'coerces reasons' do
105
- expect(described_class.coerce 'Bad request').to eq described_class.new 400
102
+ describe ".coerce" do
103
+ context "with String" do
104
+ it "coerces reasons" do
105
+ expect(described_class.coerce "Bad request").to eq described_class.new 400
106
106
  end
107
107
 
108
- it 'fails when reason is unknown' do
109
- expect { described_class.coerce 'foobar' }.to raise_error HTTP::Error
108
+ it "fails when reason is unknown" do
109
+ expect { described_class.coerce "foobar" }.to raise_error HTTP::Error
110
110
  end
111
111
  end
112
112
 
113
- context 'with Symbol' do
114
- it 'coerces symbolized reasons' do
113
+ context "with Symbol" do
114
+ it "coerces symbolized reasons" do
115
115
  expect(described_class.coerce :bad_request).to eq described_class.new 400
116
116
  end
117
117
 
118
- it 'fails when symbolized reason is unknown' do
118
+ it "fails when symbolized reason is unknown" do
119
119
  expect { described_class.coerce :foobar }.to raise_error HTTP::Error
120
120
  end
121
121
  end
122
122
 
123
- context 'with Numeric' do
124
- it 'coerces as Fixnum code' do
123
+ context "with Numeric" do
124
+ it "coerces as Fixnum code" do
125
125
  expect(described_class.coerce 200.1).to eq described_class.new 200
126
126
  end
127
127
  end
128
128
 
129
- it 'fails if coercion failed' do
129
+ it "fails if coercion failed" do
130
130
  expect { described_class.coerce true }.to raise_error HTTP::Error
131
131
  end
132
132
 
133
- it 'is aliased as `.[]`' do
133
+ it "is aliased as `.[]`" do
134
134
  expect(described_class.method :coerce).to eq described_class.method :[]
135
135
  end
136
136
  end
@@ -0,0 +1,35 @@
1
+ RSpec.describe HTTP::Response::StringBody do
2
+ subject(:body) { described_class.new "Hello, World!" }
3
+
4
+ it "has the content" do
5
+ expect(subject.to_s).to eq "Hello, World!"
6
+ end
7
+
8
+ context "when body empty" do
9
+ subject(:body) { described_class.new "" }
10
+
11
+ it "returns responds to empty? with true" do
12
+ expect(subject).to be_empty
13
+ end
14
+ end
15
+
16
+ describe "#readpartial" do
17
+ context "with size given" do
18
+ it "returns only that amount" do
19
+ expect(body.readpartial(4)).to eq "Hell"
20
+ end
21
+ end
22
+
23
+ context "without size given" do
24
+ it "returns parts of the full content" do
25
+ expect(body.readpartial).to eq "Hello, World!"
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#each" do
31
+ it "yields contents" do
32
+ expect { |b| body.each(&b) }.to yield_with_args "Hello, World!"
33
+ end
34
+ end
35
+ end
@@ -1,98 +1,117 @@
1
1
  RSpec.describe HTTP::Response do
2
- it 'includes HTTP::Headers::Mixin' do
2
+ let(:body) { "Hello world!" }
3
+ subject(:response) { HTTP::Response.new 200, "1.1", {}, body }
4
+
5
+ it "includes HTTP::Headers::Mixin" do
3
6
  expect(described_class).to include HTTP::Headers::Mixin
4
7
  end
5
8
 
6
- describe 'to_a' do
7
- let(:body) { 'Hello world' }
8
- let(:content_type) { 'text/plain' }
9
- subject { HTTP::Response.new(200, '1.1', {'Content-Type' => content_type}, body) }
9
+ describe "to_a" do
10
+ let(:body) { "Hello world" }
11
+ let(:content_type) { "text/plain" }
12
+ subject { HTTP::Response.new(200, "1.1", {"Content-Type" => content_type}, body) }
10
13
 
11
- it 'returns a Rack-like array' do
12
- expect(subject.to_a).to eq([200, {'Content-Type' => content_type}, body])
14
+ it "returns a Rack-like array" do
15
+ expect(subject.to_a).to eq([200, {"Content-Type" => content_type}, body])
13
16
  end
14
17
  end
15
18
 
16
- describe 'mime_type' do
17
- subject { HTTP::Response.new(200, '1.1', headers, '').mime_type }
19
+ describe "mime_type" do
20
+ subject { HTTP::Response.new(200, "1.1", headers, "").mime_type }
18
21
 
19
- context 'without Content-Type header' do
22
+ context "without Content-Type header" do
20
23
  let(:headers) { {} }
21
24
  it { is_expected.to be_nil }
22
25
  end
23
26
 
24
- context 'with Content-Type: text/html' do
25
- let(:headers) { {'Content-Type' => 'text/html'} }
26
- it { is_expected.to eq 'text/html' }
27
+ context "with Content-Type: text/html" do
28
+ let(:headers) { {"Content-Type" => "text/html"} }
29
+ it { is_expected.to eq "text/html" }
27
30
  end
28
31
 
29
- context 'with Content-Type: text/html; charset=utf-8' do
30
- let(:headers) { {'Content-Type' => 'text/html; charset=utf-8'} }
31
- it { is_expected.to eq 'text/html' }
32
+ context "with Content-Type: text/html; charset=utf-8" do
33
+ let(:headers) { {"Content-Type" => "text/html; charset=utf-8"} }
34
+ it { is_expected.to eq "text/html" }
32
35
  end
33
36
  end
34
37
 
35
- describe 'charset' do
36
- subject { HTTP::Response.new(200, '1.1', headers, '').charset }
38
+ describe "charset" do
39
+ subject { HTTP::Response.new(200, "1.1", headers, "").charset }
37
40
 
38
- context 'without Content-Type header' do
41
+ context "without Content-Type header" do
39
42
  let(:headers) { {} }
40
43
  it { is_expected.to be_nil }
41
44
  end
42
45
 
43
- context 'with Content-Type: text/html' do
44
- let(:headers) { {'Content-Type' => 'text/html'} }
46
+ context "with Content-Type: text/html" do
47
+ let(:headers) { {"Content-Type" => "text/html"} }
45
48
  it { is_expected.to be_nil }
46
49
  end
47
50
 
48
- context 'with Content-Type: text/html; charset=utf-8' do
49
- let(:headers) { {'Content-Type' => 'text/html; charset=utf-8'} }
50
- it { is_expected.to eq 'utf-8' }
51
+ context "with Content-Type: text/html; charset=utf-8" do
52
+ let(:headers) { {"Content-Type" => "text/html; charset=utf-8"} }
53
+ it { is_expected.to eq "utf-8" }
51
54
  end
52
55
  end
53
56
 
54
- describe '#parse' do
55
- let(:headers) { {'Content-Type' => content_type} }
57
+ describe "#parse" do
58
+ let(:headers) { {"Content-Type" => content_type} }
56
59
  let(:body) { '{"foo":"bar"}' }
57
- let(:response) { HTTP::Response.new 200, '1.1', headers, body }
60
+ let(:response) { HTTP::Response.new 200, "1.1", headers, body }
58
61
 
59
- context 'with known content type' do
60
- let(:content_type) { 'application/json' }
61
- it 'returns parsed body' do
62
- expect(response.parse).to eq 'foo' => 'bar'
62
+ context "with known content type" do
63
+ let(:content_type) { "application/json" }
64
+ it "returns parsed body" do
65
+ expect(response.parse).to eq "foo" => "bar"
63
66
  end
64
67
  end
65
68
 
66
- context 'with unknown content type' do
67
- let(:content_type) { 'application/deadbeef' }
68
- it 'raises HTTP::Error' do
69
+ context "with unknown content type" do
70
+ let(:content_type) { "application/deadbeef" }
71
+ it "raises HTTP::Error" do
69
72
  expect { response.parse }.to raise_error HTTP::Error
70
73
  end
71
74
  end
72
75
 
73
- context 'with explicitly given mime type' do
74
- let(:content_type) { 'application/deadbeef' }
75
- it 'ignores mime_type of response' do
76
- expect(response.parse 'application/json').to eq 'foo' => 'bar'
76
+ context "with explicitly given mime type" do
77
+ let(:content_type) { "application/deadbeef" }
78
+ it "ignores mime_type of response" do
79
+ expect(response.parse "application/json").to eq "foo" => "bar"
77
80
  end
78
81
 
79
- it 'supports MIME type aliases' do
80
- expect(response.parse :json).to eq 'foo' => 'bar'
82
+ it "supports MIME type aliases" do
83
+ expect(response.parse :json).to eq "foo" => "bar"
81
84
  end
82
85
  end
83
86
  end
84
87
 
85
- describe '#flush' do
86
- let(:body) { double :to_s => '' }
87
- let(:response) { HTTP::Response.new 200, '1.1', {}, body }
88
+ describe "#flush" do
89
+ let(:body) { double :to_s => "" }
90
+ let(:response) { HTTP::Response.new 200, "1.1", {}, body }
88
91
 
89
- it 'returns response self-reference' do
92
+ it "returns response self-reference" do
90
93
  expect(response.flush).to be response
91
94
  end
92
95
 
93
- it 'flushes body' do
96
+ it "flushes body" do
94
97
  expect(body).to receive :to_s
95
98
  response.flush
96
99
  end
97
100
  end
101
+
102
+ describe "#inspect" do
103
+ it "returns human0friendly response representation" do
104
+ headers = {:content_type => "text/plain"}
105
+ body = double :to_s => "foobar"
106
+ response = HTTP::Response.new(200, "1.1", headers, body)
107
+
108
+ expect(response.inspect)
109
+ .to eq '#<HTTP::Response/1.1 200 OK {"Content-Type"=>"text/plain"}>'
110
+ end
111
+ end
112
+
113
+ describe "#caching" do
114
+ subject { response.caching }
115
+ it { is_expected.to be_a HTTP::Response::Caching }
116
+ end
98
117
  end
@@ -1,139 +1,166 @@
1
- require 'json'
1
+ require "json"
2
+
3
+ require "support/dummy_server"
4
+ require "support/proxy_server"
2
5
 
3
6
  RSpec.describe HTTP do
4
- let(:test_endpoint) { "http://#{ExampleServer::ADDR}" }
7
+ run_server(:dummy) { DummyServer.new }
5
8
 
6
- context 'getting resources' do
7
- it 'is easy' do
8
- response = HTTP.get test_endpoint
9
+ context "getting resources" do
10
+ it "is easy" do
11
+ response = HTTP.get dummy.endpoint
9
12
  expect(response.to_s).to match(/<!doctype html>/)
10
13
  end
11
14
 
12
- context 'with URI instance' do
13
- it 'is easy' do
14
- response = HTTP.get URI test_endpoint
15
+ context "with URI instance" do
16
+ it "is easy" do
17
+ response = HTTP.get URI dummy.endpoint
15
18
  expect(response.to_s).to match(/<!doctype html>/)
16
19
  end
17
20
  end
18
21
 
19
- context 'with query string parameters' do
20
- it 'is easy' do
21
- response = HTTP.get "#{test_endpoint}/params", :params => {:foo => 'bar'}
22
+ context "with query string parameters" do
23
+ it "is easy" do
24
+ response = HTTP.get "#{dummy.endpoint}/params", :params => {:foo => "bar"}
22
25
  expect(response.to_s).to match(/Params!/)
23
26
  end
24
27
  end
25
28
 
26
- context 'with query string parameters in the URI and opts hash' do
27
- it 'includes both' do
28
- response = HTTP.get "#{test_endpoint}/multiple-params?foo=bar", :params => {:baz => 'quux'}
29
+ context "with query string parameters in the URI and opts hash" do
30
+ it "includes both" do
31
+ response = HTTP.get "#{dummy.endpoint}/multiple-params?foo=bar", :params => {:baz => "quux"}
29
32
  expect(response.to_s).to match(/More Params!/)
30
33
  end
31
34
  end
32
35
 
33
- context 'with headers' do
34
- it 'is easy' do
35
- response = HTTP.accept('application/json').get test_endpoint
36
- expect(response.to_s.include?('json')).to be true
36
+ context "with headers" do
37
+ it "is easy" do
38
+ response = HTTP.accept("application/json").get dummy.endpoint
39
+ expect(response.to_s.include?("json")).to be true
37
40
  end
38
41
  end
39
42
  end
40
43
 
41
- context 'with http proxy address and port' do
42
- it 'proxies the request' do
43
- response = HTTP.via('127.0.0.1', 8080).get test_endpoint
44
- expect(response.headers['X-Proxied']).to eq 'true'
45
- end
46
- end
44
+ describe ".via" do
45
+ context "anonymous proxy" do
46
+ run_server(:proxy) { ProxyServer.new }
47
47
 
48
- context 'with http proxy address, port username and password' do
49
- it 'proxies the request' do
50
- response = HTTP.via('127.0.0.1', 8081, 'username', 'password').get test_endpoint
51
- expect(response.headers['X-Proxied']).to eq 'true'
52
- end
48
+ it "proxies the request" do
49
+ response = HTTP.via(proxy.addr, proxy.port).get dummy.endpoint
50
+ expect(response.headers["X-Proxied"]).to eq "true"
51
+ end
53
52
 
54
- it 'responds with the endpoint\'s body' do
55
- response = HTTP.via('127.0.0.1', 8081, 'username', 'password').get test_endpoint
56
- expect(response.to_s).to match(/<!doctype html>/)
57
- end
58
- end
53
+ it "responds with the endpoint's body" do
54
+ response = HTTP.via(proxy.addr, proxy.port).get dummy.endpoint
55
+ expect(response.to_s).to match(/<!doctype html>/)
56
+ end
59
57
 
60
- context 'with http proxy address, port, with wrong username and password' do
61
- it 'responds with 407' do
62
- response = HTTP.via('127.0.0.1', 8081, 'user', 'pass').get test_endpoint
63
- expect(response.status).to eq(407)
58
+ it "raises an argument error if no port given" do
59
+ expect { HTTP.via(proxy.addr) }.to raise_error HTTP::RequestError
60
+ end
61
+
62
+ it "ignores credentials" do
63
+ response = HTTP.via(proxy.addr, proxy.port, "username", "password").get dummy.endpoint
64
+ expect(response.to_s).to match(/<!doctype html>/)
65
+ end
64
66
  end
65
- end
66
67
 
67
- context 'without proxy port' do
68
- it 'raises an argument error' do
69
- expect { HTTP.via('127.0.0.1') }.to raise_error HTTP::RequestError
68
+ context "proxy with authentication" do
69
+ run_server(:proxy) { AuthProxyServer.new }
70
+
71
+ it "proxies the request" do
72
+ response = HTTP.via(proxy.addr, proxy.port, "username", "password").get dummy.endpoint
73
+ expect(response.headers["X-Proxied"]).to eq "true"
74
+ end
75
+
76
+ it "responds with the endpoint's body" do
77
+ response = HTTP.via(proxy.addr, proxy.port, "username", "password").get dummy.endpoint
78
+ expect(response.to_s).to match(/<!doctype html>/)
79
+ end
80
+
81
+ it "responds with 407 when wrong credentials given" do
82
+ response = HTTP.via(proxy.addr, proxy.port, "user", "pass").get dummy.endpoint
83
+ expect(response.status).to eq(407)
84
+ end
85
+
86
+ it "responds with 407 if no credentials given" do
87
+ response = HTTP.via(proxy.addr, proxy.port).get dummy.endpoint
88
+ expect(response.status).to eq(407)
89
+ end
70
90
  end
71
91
  end
72
92
 
73
- context 'posting forms to resources' do
74
- it 'is easy' do
75
- response = HTTP.post "#{test_endpoint}/form", :form => {:example => 'testing-form'}
76
- expect(response.to_s).to eq('passed :)')
93
+ context "posting forms to resources" do
94
+ it "is easy" do
95
+ response = HTTP.post "#{dummy.endpoint}/form", :form => {:example => "testing-form"}
96
+ expect(response.to_s).to eq("passed :)")
77
97
  end
78
98
  end
79
99
 
80
- context 'posting with an explicit body' do
81
- it 'is easy' do
82
- response = HTTP.post "#{test_endpoint}/body", :body => 'testing-body'
83
- expect(response.to_s).to eq('passed :)')
100
+ context "posting with an explicit body" do
101
+ it "is easy" do
102
+ response = HTTP.post "#{dummy.endpoint}/body", :body => "testing-body"
103
+ expect(response.to_s).to eq("passed :)")
84
104
  end
85
105
  end
86
106
 
87
- context 'with redirects' do
88
- it 'is easy for 301' do
89
- response = HTTP.with_follow(true).get("#{test_endpoint}/redirect-301")
107
+ context "with redirects" do
108
+ it "is easy for 301" do
109
+ response = HTTP.with_follow(true).get("#{dummy.endpoint}/redirect-301")
90
110
  expect(response.to_s).to match(/<!doctype html>/)
91
111
  end
92
112
 
93
- it 'is easy for 302' do
94
- response = HTTP.with_follow(true).get("#{test_endpoint}/redirect-302")
113
+ it "is easy for 302" do
114
+ response = HTTP.with_follow(true).get("#{dummy.endpoint}/redirect-302")
95
115
  expect(response.to_s).to match(/<!doctype html>/)
96
116
  end
97
-
98
117
  end
99
118
 
100
- context 'head requests' do
101
- it 'is easy' do
102
- response = HTTP.head test_endpoint
119
+ context "head requests" do
120
+ it "is easy" do
121
+ response = HTTP.head dummy.endpoint
103
122
  expect(response.status).to eq(200)
104
- expect(response['content-type']).to match(/html/)
123
+ expect(response["content-type"]).to match(/html/)
105
124
  end
106
125
  end
107
126
 
108
- describe '.auth' do
109
- it 'sets Authorization header to the given value' do
110
- client = HTTP.auth 'abc'
111
- expect(client.default_headers[:authorization]).to eq 'abc'
127
+ describe ".auth" do
128
+ it "sets Authorization header to the given value" do
129
+ client = HTTP.auth "abc"
130
+ expect(client.default_headers[:authorization]).to eq "abc"
112
131
  end
113
132
 
114
- it 'accepts any #to_s object' do
115
- client = HTTP.auth double :to_s => 'abc'
116
- expect(client.default_headers[:authorization]).to eq 'abc'
133
+ it "accepts any #to_s object" do
134
+ client = HTTP.auth double :to_s => "abc"
135
+ expect(client.default_headers[:authorization]).to eq "abc"
117
136
  end
118
137
  end
119
138
 
120
- describe '.basic_auth' do
121
- it 'fails when options is not a Hash' do
122
- expect { HTTP.basic_auth '[FOOBAR]' }.to raise_error
139
+ describe ".basic_auth" do
140
+ it "fails when options is not a Hash" do
141
+ expect { HTTP.basic_auth "[FOOBAR]" }.to raise_error
123
142
  end
124
143
 
125
- it 'fails when :pass is not given' do
126
- expect { HTTP.basic_auth :user => '[USER]' }.to raise_error
144
+ it "fails when :pass is not given" do
145
+ expect { HTTP.basic_auth :user => "[USER]" }.to raise_error
127
146
  end
128
147
 
129
- it 'fails when :user is not given' do
130
- expect { HTTP.basic_auth :pass => '[PASS]' }.to raise_error
148
+ it "fails when :user is not given" do
149
+ expect { HTTP.basic_auth :pass => "[PASS]" }.to raise_error
131
150
  end
132
151
 
133
- it 'sets Authorization header with proper BasicAuth value' do
134
- client = HTTP.basic_auth :user => 'foo', :pass => 'bar'
152
+ it "sets Authorization header with proper BasicAuth value" do
153
+ client = HTTP.basic_auth :user => "foo", :pass => "bar"
135
154
  expect(client.default_headers[:authorization])
136
155
  .to match(/^Basic [A-Za-z0-9+\/]+=*$/)
137
156
  end
138
157
  end
158
+
159
+ describe ".with_cache" do
160
+ it "sets cache option" do
161
+ cache = double(:cache, :perform => nil)
162
+ client = HTTP.with_cache cache
163
+ expect(client.default_options[:cache]).to eq cache
164
+ end
165
+ end
139
166
  end