typhoeus 0.6.3 → 0.6.4

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 (61) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +10 -0
  5. data/CHANGELOG.md +7 -1
  6. data/CONTRIBUTING.md +16 -0
  7. data/Guardfile +9 -0
  8. data/README.md +303 -1
  9. data/UPGRADE.md +55 -0
  10. data/lib/rack/typhoeus/middleware/params_decoder.rb +1 -1
  11. data/lib/rack/typhoeus/middleware/params_decoder/helper.rb +6 -2
  12. data/lib/typhoeus/adapters/faraday.rb +4 -1
  13. data/lib/typhoeus/easy_factory.rb +36 -15
  14. data/lib/typhoeus/hydra/before.rb +2 -1
  15. data/lib/typhoeus/hydra/cacheable.rb +1 -0
  16. data/lib/typhoeus/hydra/memoizable.rb +1 -0
  17. data/lib/typhoeus/hydra/queueable.rb +15 -3
  18. data/lib/typhoeus/request.rb +6 -2
  19. data/lib/typhoeus/request/marshal.rb +3 -2
  20. data/lib/typhoeus/response/informations.rb +4 -0
  21. data/lib/typhoeus/version.rb +1 -1
  22. data/perf/profile.rb +14 -0
  23. data/perf/vs_nethttp.rb +64 -0
  24. data/spec/rack/typhoeus/middleware/params_decoder/helper_spec.rb +132 -0
  25. data/spec/rack/typhoeus/middleware/params_decoder_spec.rb +31 -0
  26. data/spec/spec_helper.rb +35 -0
  27. data/spec/support/localhost_server.rb +94 -0
  28. data/spec/support/server.rb +108 -0
  29. data/spec/typhoeus/adapters/faraday_spec.rb +245 -0
  30. data/spec/typhoeus/config_spec.rb +15 -0
  31. data/spec/typhoeus/easy_factory_spec.rb +96 -0
  32. data/spec/typhoeus/errors/no_stub_spec.rb +13 -0
  33. data/spec/typhoeus/expectation_spec.rb +273 -0
  34. data/spec/typhoeus/hydra/addable_spec.rb +22 -0
  35. data/spec/typhoeus/hydra/before_spec.rb +97 -0
  36. data/spec/typhoeus/hydra/block_connection_spec.rb +18 -0
  37. data/spec/typhoeus/hydra/cacheable_spec.rb +68 -0
  38. data/spec/typhoeus/hydra/memoizable_spec.rb +53 -0
  39. data/spec/typhoeus/hydra/queueable_spec.rb +34 -0
  40. data/spec/typhoeus/hydra/runnable_spec.rb +155 -0
  41. data/spec/typhoeus/hydra/stubbable_spec.rb +28 -0
  42. data/spec/typhoeus/hydra_spec.rb +26 -0
  43. data/spec/typhoeus/pool_spec.rb +79 -0
  44. data/spec/typhoeus/request/actions_spec.rb +19 -0
  45. data/spec/typhoeus/request/before_spec.rb +92 -0
  46. data/spec/typhoeus/request/block_connection_spec.rb +75 -0
  47. data/spec/typhoeus/request/cacheable_spec.rb +80 -0
  48. data/spec/typhoeus/request/callbacks_spec.rb +91 -0
  49. data/spec/typhoeus/request/marshal_spec.rb +62 -0
  50. data/spec/typhoeus/request/memoizable_spec.rb +34 -0
  51. data/spec/typhoeus/request/operations_spec.rb +70 -0
  52. data/spec/typhoeus/request/responseable_spec.rb +13 -0
  53. data/spec/typhoeus/request/stubbable_spec.rb +27 -0
  54. data/spec/typhoeus/request_spec.rb +131 -0
  55. data/spec/typhoeus/response/header_spec.rb +97 -0
  56. data/spec/typhoeus/response/informations_spec.rb +218 -0
  57. data/spec/typhoeus/response/status_spec.rb +218 -0
  58. data/spec/typhoeus/response_spec.rb +81 -0
  59. data/spec/typhoeus_spec.rb +105 -0
  60. data/typhoeus.gemspec +25 -0
  61. metadata +101 -27
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Config do
4
+ let(:config) { Typhoeus::Config }
5
+
6
+ [:block_connection, :memoize, :verbose, :cache].each do |name|
7
+ it "responds to #{name}" do
8
+ expect(config).to respond_to(name)
9
+ end
10
+
11
+ it "responds to #{name}=" do
12
+ expect(config).to respond_to("#{name}=")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::EasyFactory do
4
+ let(:base_url) { "http://localhost:3001" }
5
+ let(:hydra) { Typhoeus::Hydra.new(:max_concurrency => 0) }
6
+ let(:options) { {} }
7
+ let(:request) { Typhoeus::Request.new(base_url, options) }
8
+ let(:easy_factory) { described_class.new(request, hydra) }
9
+
10
+ describe "#get" do
11
+ context "when option[:cache_ttl]" do
12
+ let(:options) { {:cache_ttl => 1} }
13
+
14
+ it "creates Ethon::Easy" do
15
+ expect(easy_factory.get).to be_a(Ethon::Easy)
16
+ end
17
+ end
18
+
19
+ context "when invalid option" do
20
+ let(:options) { {:invalid => 1} }
21
+
22
+ it "reraises" do
23
+ expect{ easy_factory.get }.to raise_error(Ethon::Errors::InvalidOption)
24
+ end
25
+ end
26
+
27
+ context "when removed option" do
28
+ let(:options) { {:cache_timeout => 1} }
29
+
30
+ it "reraises with help" do
31
+ expect{ easy_factory.get }.to raise_error(
32
+ Ethon::Errors::InvalidOption, /The option cache_timeout was removed/
33
+ )
34
+ end
35
+ end
36
+
37
+ context "when changed option" do
38
+ let(:options) { {:proxy_auth_method => 1} }
39
+
40
+ it "reraises with help" do
41
+ expect{ easy_factory.get }.to raise_error(
42
+ Ethon::Errors::InvalidOption, /Please try proxyauth instead of proxy_auth_method/
43
+ )
44
+ end
45
+ end
46
+
47
+ context "when renamed option" do
48
+ let(:options) { {:connect_timeout => 1} }
49
+
50
+ it "warns" do
51
+ easy_factory.should_receive(:warn).with(
52
+ "Deprecated option connect_timeout. Please use connecttimeout instead."
53
+ )
54
+ easy_factory.get
55
+ end
56
+
57
+ it "passes correct option" do
58
+ easy_factory.should_receive(:warn)
59
+ easy_factory.easy.should_receive(:connecttimeout=).with(1)
60
+ easy_factory.get
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#set_callback" do
66
+ it "sets easy.on_complete callback" do
67
+ easy_factory.easy.should_receive(:on_complete)
68
+ easy_factory.send(:set_callback)
69
+ end
70
+
71
+ it "finishes request" do
72
+ easy_factory.send(:set_callback)
73
+ request.should_receive(:finish)
74
+ easy_factory.easy.complete
75
+ end
76
+
77
+ it "resets easy" do
78
+ easy_factory.send(:set_callback)
79
+ easy_factory.easy.should_receive(:reset)
80
+ easy_factory.easy.complete
81
+ end
82
+
83
+ it "pushes easy back into the pool" do
84
+ easy_factory.send(:set_callback)
85
+ easy_factory.easy.complete
86
+ expect(Typhoeus::Pool.send(:easies)).to include(easy_factory.easy)
87
+ end
88
+
89
+ it "adds next request" do
90
+ easy_factory.hydra.instance_variable_set(:@queued_requests, [request])
91
+ easy_factory.hydra.should_receive(:add).with(request)
92
+ easy_factory.send(:set_callback)
93
+ easy_factory.easy.complete
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Errors::NoStub do
4
+ let(:base_url) { "localhost:3001" }
5
+ let(:request) { Typhoeus::Request.new(base_url) }
6
+ let(:message) { "The connection is blocked and no stub defined: " }
7
+
8
+ subject { Typhoeus::Errors::NoStub }
9
+
10
+ it "displays the request url" do
11
+ expect { raise subject.new(request) }.to raise_error(subject, message + base_url)
12
+ end
13
+ end
@@ -0,0 +1,273 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Expectation do
4
+ let(:options) { {} }
5
+ let(:base_url) { "www.example.com" }
6
+ let(:expectation) { described_class.new(base_url, options) }
7
+
8
+ describe ".new" do
9
+ it "sets base_url" do
10
+ expect(expectation.instance_variable_get(:@base_url)).to eq(base_url)
11
+ end
12
+
13
+ it "sets options" do
14
+ expect(expectation.instance_variable_get(:@options)).to eq(options)
15
+ end
16
+
17
+ it "initializes response_counter" do
18
+ expect(expectation.instance_variable_get(:@response_counter)).to eq(0)
19
+ end
20
+ end
21
+
22
+ describe ".all" do
23
+ context "when @expectations nil" do
24
+ it "returns empty array" do
25
+ expect(Typhoeus::Expectation.all).to eq([])
26
+ end
27
+ end
28
+
29
+ context "when @expectations not nil" do
30
+ let(:expectations) { [1] }
31
+
32
+ it "returns @expectations" do
33
+ Typhoeus::Expectation.instance_variable_set(:@expectations, expectations)
34
+ expect(Typhoeus::Expectation.all).to be(expectations)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe ".clear" do
40
+ let(:expectations) { double(:clear) }
41
+
42
+ it "clears all" do
43
+ expectations.should_receive(:clear)
44
+ Typhoeus::Expectation.instance_variable_set(:@expectations, expectations)
45
+ Typhoeus::Expectation.clear
46
+ Typhoeus::Expectation.instance_variable_set(:@expectations, nil)
47
+ end
48
+ end
49
+
50
+ describe ".response_for" do
51
+ let(:request) { Typhoeus::Request.new("") }
52
+ let(:stubbed_response) { Typhoeus::Response.new }
53
+
54
+ it "finds a matching expectation and returns its next response" do
55
+ Typhoeus::Expectation.all << expectation
56
+ expectation.should_receive(:matches?).with(request).and_return(true)
57
+ expectation.should_receive(:response).with(request).and_return(stubbed_response)
58
+
59
+ response = Typhoeus::Expectation.response_for(request)
60
+
61
+ expect(response).to be(stubbed_response)
62
+ end
63
+
64
+ it "returns nil if no matching expectation is found" do
65
+ response = Typhoeus::Expectation.response_for(request)
66
+ expect(response).to be(nil)
67
+ end
68
+ end
69
+
70
+ describe "#stubbed_from" do
71
+ it "sets value" do
72
+ expectation.stubbed_from(:webmock)
73
+ expect(expectation.from).to eq(:webmock)
74
+ end
75
+
76
+ it "returns self" do
77
+ expect(expectation.stubbed_from(:webmock)).to be(expectation)
78
+ end
79
+ end
80
+
81
+ describe "#and_return" do
82
+ context "when value" do
83
+ it "adds to responses" do
84
+ expectation.and_return(1)
85
+ expect(expectation.responses).to eq([1])
86
+ end
87
+ end
88
+
89
+ context "when array" do
90
+ it "adds to responses" do
91
+ pending
92
+ expectation.and_return([1, 2])
93
+ expect(expectation.responses).to eq([1, 2])
94
+ end
95
+ end
96
+
97
+ context "when block" do
98
+ it "adds to responses" do
99
+ block = Proc.new {}
100
+ expectation.and_return(&block)
101
+ expect(expectation.responses).to eq([block])
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#responses" do
107
+ it "returns responses" do
108
+ expect(expectation.responses).to be_a(Array)
109
+ end
110
+ end
111
+
112
+ describe "#response" do
113
+ let(:request) { Typhoeus::Request.new("") }
114
+
115
+ before { expectation.instance_variable_set(:@responses, responses) }
116
+
117
+ context "when one response" do
118
+ context "is pre-constructed" do
119
+ let(:responses) { [Typhoeus::Response.new] }
120
+
121
+ it "returns response" do
122
+ expect(expectation.response(request)).to be(responses[0])
123
+ end
124
+ end
125
+
126
+ context "is lazily-constructed" do
127
+ def construct_response(request)
128
+ @request_from_response_construction = request
129
+ lazily_constructed_response
130
+ end
131
+
132
+ let(:lazily_constructed_response) { Typhoeus::Response.new }
133
+ let(:responses) { [ Proc.new { |request| construct_response(request) } ] }
134
+
135
+ it "returns response" do
136
+ expect(expectation.response(request)).to be(lazily_constructed_response)
137
+ expect(@request_from_response_construction).to be(request)
138
+ end
139
+ end
140
+ end
141
+
142
+ context "when multiple responses" do
143
+ let(:responses) { [Typhoeus::Response.new, Typhoeus::Response.new, Typhoeus::Response.new] }
144
+
145
+ it "returns one by one" do
146
+ 3.times do |i|
147
+ expect(expectation.response(request)).to be(responses[i])
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "#matches?" do
154
+ let(:request) { double(:base_url => nil) }
155
+
156
+ it "calls url_match?" do
157
+ expectation.should_receive(:url_match?)
158
+ expectation.matches?(request)
159
+ end
160
+
161
+ it "calls options_match?" do
162
+ expectation.should_receive(:url_match?).and_return(true)
163
+ expectation.should_receive(:options_match?)
164
+ expectation.matches?(request)
165
+ end
166
+ end
167
+
168
+ describe "#url_match?" do
169
+ let(:request_url) { "www.example.com" }
170
+ let(:request) { Typhoeus::Request.new(request_url) }
171
+ let(:url_match) { expectation.method(:url_match?).call(request.base_url) }
172
+
173
+ context "when string" do
174
+ context "when match" do
175
+ it "returns true" do
176
+ expect(url_match).to be_true
177
+ end
178
+ end
179
+
180
+ context "when no match" do
181
+ let(:base_url) { "no_match" }
182
+
183
+ it "returns false" do
184
+ expect(url_match).to be_false
185
+ end
186
+ end
187
+ end
188
+
189
+ context "when regexp" do
190
+ context "when match" do
191
+ let(:base_url) { /example/ }
192
+
193
+ it "returns true" do
194
+ expect(url_match).to be_true
195
+ end
196
+ end
197
+
198
+ context "when no match" do
199
+ let(:base_url) { /nomatch/ }
200
+
201
+ it "returns false" do
202
+ expect(url_match).to be_false
203
+ end
204
+ end
205
+ end
206
+
207
+ context "when nil" do
208
+ let(:base_url) { nil }
209
+
210
+ it "returns true" do
211
+ expect(url_match).to be_true
212
+ end
213
+ end
214
+
215
+ context "when not string, regexp, nil" do
216
+ let(:base_url) { 1 }
217
+
218
+ it "returns false" do
219
+ expect(url_match).to be_false
220
+ end
221
+ end
222
+ end
223
+
224
+ describe "options_match?" do
225
+ let(:request_options) { {} }
226
+ let(:request) { Typhoeus::Request.new(nil, request_options) }
227
+ let(:options_match) { expectation.method(:options_match?).call(request) }
228
+
229
+ context "when match" do
230
+ let(:options) { { :a => 1 } }
231
+ let(:request_options) { options }
232
+
233
+ it "returns true" do
234
+ expect(options_match).to be_true
235
+ end
236
+ end
237
+
238
+ context "when options are a subset from request_options" do
239
+ let(:options) { { :a => 1 } }
240
+ let(:request_options) { { :a => 1, :b => 2 } }
241
+
242
+ it "returns true" do
243
+ expect(options_match).to be_true
244
+ end
245
+ end
246
+
247
+ context "when options are nested" do
248
+ let(:options) { { :a => { :b => 1 } } }
249
+ let(:request_options) { options }
250
+
251
+ it "returns true" do
252
+ expect(options_match).to be_true
253
+ end
254
+ end
255
+
256
+ context "when options contains an array" do
257
+ let(:options) { { :a => [1, 2] } }
258
+ let(:request_options) { options }
259
+
260
+ it "returns true" do
261
+ expect(options_match).to be_true
262
+ end
263
+ end
264
+
265
+ context "when no match" do
266
+ let(:options) { { :a => 1 } }
267
+
268
+ it "returns false" do
269
+ expect(options_match).to be_false
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Hydra::Addable do
4
+ let(:hydra) { Typhoeus::Hydra.new() }
5
+ let(:request) { Typhoeus::Request.new("localhost:3001", {:method => :get}) }
6
+
7
+ it "asks easy factory for an easy" do
8
+ multi = double
9
+ Typhoeus::EasyFactory.should_receive(:new).with(request, hydra).and_return(double(:get => 1))
10
+ hydra.should_receive(:multi).and_return(multi)
11
+ multi.should_receive(:add).with(1)
12
+ hydra.add(request)
13
+ end
14
+
15
+ it "adds easy to multi" do
16
+ multi = double
17
+ Typhoeus::EasyFactory.should_receive(:new).with(request, hydra).and_return(double(:get => 1))
18
+ hydra.should_receive(:multi).and_return(multi)
19
+ multi.should_receive(:add).with(1)
20
+ hydra.add(request)
21
+ end
22
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Hydra::Before do
4
+ let(:request) { Typhoeus::Request.new("") }
5
+ let(:hydra) { Typhoeus::Hydra.new }
6
+
7
+ describe "#add" do
8
+ context "when before" do
9
+ context "when one" do
10
+ it "executes" do
11
+ Typhoeus.before { |r| String.new(r.base_url) }
12
+ String.should_receive(:new).and_return("")
13
+ hydra.add(request)
14
+ end
15
+
16
+ context "when true" do
17
+ it "calls super" do
18
+ Typhoeus.before { true }
19
+ Typhoeus::Expectation.should_receive(:response_for)
20
+ hydra.add(request)
21
+ end
22
+ end
23
+
24
+ context "when falsy" do
25
+ context "when queue requests" do
26
+ let(:queued_request) { Typhoeus::Request.new("") }
27
+
28
+ before { hydra.queue(queued_request) }
29
+
30
+ it "dequeues" do
31
+ Typhoeus.before { false }
32
+ hydra.add(request)
33
+ expect(hydra.queued_requests).to be_empty
34
+ end
35
+ end
36
+
37
+ context "when false" do
38
+ it "doesn't call super" do
39
+ Typhoeus.before { false }
40
+ Typhoeus::Expectation.should_receive(:response_for).never
41
+ hydra.add(request)
42
+ end
43
+ end
44
+
45
+ context "when response" do
46
+ it "doesn't call super" do
47
+ Typhoeus.before { Typhoeus::Response.new }
48
+ Typhoeus::Expectation.should_receive(:response_for).never
49
+ hydra.add(request)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ context "when multi" do
56
+ context "when all true" do
57
+ before { 3.times { Typhoeus.before { |r| String.new(r.base_url) } } }
58
+
59
+ it "calls super" do
60
+ Typhoeus::Expectation.should_receive(:response_for)
61
+ hydra.add(request)
62
+ end
63
+
64
+ it "executes all" do
65
+ String.should_receive(:new).exactly(3).times.and_return("")
66
+ hydra.add(request)
67
+ end
68
+ end
69
+
70
+ context "when middle false" do
71
+ before do
72
+ Typhoeus.before { |r| String.new(r.base_url) }
73
+ Typhoeus.before { |r| String.new(r.base_url); nil }
74
+ Typhoeus.before { |r| String.new(r.base_url) }
75
+ end
76
+
77
+ it "doesn't call super" do
78
+ Typhoeus::Expectation.should_receive(:response_for).never
79
+ hydra.add(request)
80
+ end
81
+
82
+ it "executes only two" do
83
+ String.should_receive(:new).exactly(2).times.and_return("")
84
+ hydra.add(request)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ context "when no before" do
91
+ it "calls super" do
92
+ Typhoeus::Expectation.should_receive(:response_for)
93
+ hydra.add(request)
94
+ end
95
+ end
96
+ end
97
+ end