webmock 1.7.10 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -2
- data/CHANGELOG.md +98 -24
- data/Gemfile +2 -3
- data/README.md +45 -4
- data/Rakefile +2 -2
- data/lib/webmock.rb +3 -0
- data/lib/webmock/api.rb +34 -6
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +4 -41
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +1 -1
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +94 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +31 -4
- data/lib/webmock/http_lib_adapters/net_http.rb +2 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +4 -3
- data/lib/webmock/matchers/hash_including_matcher.rb +25 -0
- data/lib/webmock/rack_response.rb +8 -1
- data/lib/webmock/request_pattern.rb +108 -77
- data/lib/webmock/request_signature.rb +1 -0
- data/lib/webmock/stub_registry.rb +9 -8
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +5 -2
- data/minitest/webmock_spec.rb +22 -2
- data/spec/acceptance/curb/curb_spec_helper.rb +12 -2
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +42 -33
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +4 -2
- data/spec/acceptance/excon/excon_spec.rb +15 -0
- data/spec/acceptance/excon/excon_spec_helper.rb +37 -0
- data/spec/acceptance/net_http/net_http_spec.rb +7 -0
- data/spec/acceptance/net_http/net_http_spec_helper.rb +3 -1
- data/spec/acceptance/patron/patron_spec.rb +12 -3
- data/spec/acceptance/patron/patron_spec_helper.rb +2 -2
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +3 -3
- data/spec/acceptance/shared/callbacks.rb +22 -6
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +21 -0
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +10 -11
- data/spec/acceptance/shared/precedence_of_stubs.rb +1 -1
- data/spec/acceptance/shared/request_expectations.rb +49 -3
- data/spec/acceptance/shared/returning_declared_responses.rb +9 -21
- data/spec/acceptance/shared/stubbing_requests.rb +80 -4
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +1 -1
- data/spec/acceptance/webmock_shared.rb +11 -8
- data/spec/spec_helper.rb +3 -3
- data/spec/support/my_rack_app.rb +25 -1
- data/spec/support/webmock_server.rb +9 -6
- data/spec/unit/rack_response_spec.rb +18 -0
- data/spec/unit/request_pattern_spec.rb +205 -96
- data/spec/unit/request_signature_spec.rb +36 -34
- data/spec/unit/util/uri_spec.rb +14 -2
- data/test/shared_test.rb +31 -2
- data/webmock.gemspec +9 -7
- metadata +86 -73
@@ -0,0 +1,21 @@
|
|
1
|
+
shared_context "complex cross-concern behaviors" do |*adapter_info|
|
2
|
+
it 'allows a response with multiple values for the same header to be recorded and played back exactly as-is' do
|
3
|
+
WebMock.allow_net_connect!
|
4
|
+
|
5
|
+
recorded_response = nil
|
6
|
+
WebMock.after_request { |_,r| recorded_response = r }
|
7
|
+
real_response = http_request(:get, webmock_server_url)
|
8
|
+
|
9
|
+
stub_request(:get, webmock_server_url).to_return(
|
10
|
+
:status => recorded_response.status,
|
11
|
+
:body => recorded_response.body,
|
12
|
+
:headers => recorded_response.headers
|
13
|
+
)
|
14
|
+
|
15
|
+
played_back_response = http_request(:get, webmock_server_url)
|
16
|
+
|
17
|
+
played_back_response.headers.keys.should include('Set-Cookie')
|
18
|
+
played_back_response.should == real_response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
shared_context "enabled and disabled webmock" do
|
1
|
+
shared_context "enabled and disabled webmock" do |*adapter_info|
|
2
2
|
describe "when webmock is disabled" do
|
3
3
|
before(:each) do
|
4
4
|
WebMock.disable!
|
@@ -41,28 +41,27 @@ end
|
|
41
41
|
|
42
42
|
shared_context "disabled WebMock" do
|
43
43
|
it "should not register executed requests" do
|
44
|
-
http_request(:get,
|
45
|
-
a_request(:get,
|
44
|
+
http_request(:get, webmock_server_url)
|
45
|
+
a_request(:get, webmock_server_url).should_not have_been_made
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should not block unstubbed requests" do
|
49
49
|
lambda {
|
50
|
-
http_request(:get,
|
50
|
+
http_request(:get, webmock_server_url)
|
51
51
|
}.should_not raise_error
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should return real response even if there are stubs" do
|
55
55
|
stub_request(:get, /.*/).to_return(:body => "x")
|
56
|
-
http_request(:get,
|
57
|
-
status.should == "302"
|
56
|
+
http_request(:get, webmock_server_url).body.should == "hello world"
|
58
57
|
end
|
59
58
|
|
60
59
|
it "should not invoke any callbacks" do
|
61
60
|
WebMock.reset_callbacks
|
62
|
-
stub_request(:get,
|
61
|
+
stub_request(:get, webmock_server_url)
|
63
62
|
@called = nil
|
64
63
|
WebMock.after_request { @called = 1 }
|
65
|
-
http_request(:get,
|
64
|
+
http_request(:get, webmock_server_url)
|
66
65
|
@called.should == nil
|
67
66
|
end
|
68
67
|
end
|
@@ -70,8 +69,8 @@ end
|
|
70
69
|
shared_context "enabled WebMock" do
|
71
70
|
it "should register executed requests" do
|
72
71
|
WebMock.allow_net_connect!
|
73
|
-
http_request(:get,
|
74
|
-
a_request(:get,
|
72
|
+
http_request(:get, webmock_server_url)
|
73
|
+
a_request(:get, webmock_server_url).should have_been_made
|
75
74
|
end
|
76
75
|
|
77
76
|
it "should block unstubbed requests" do
|
@@ -90,7 +89,7 @@ shared_context "enabled WebMock" do
|
|
90
89
|
WebMock.reset_callbacks
|
91
90
|
@called = nil
|
92
91
|
WebMock.after_request { @called = 1 }
|
93
|
-
http_request(:get,
|
92
|
+
http_request(:get, webmock_server_url)
|
94
93
|
@called.should == 1
|
95
94
|
end
|
96
95
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
shared_context "precedence of stubs" do
|
1
|
+
shared_context "precedence of stubs" do |*adapter_info|
|
2
2
|
describe "when choosing a matching request stub" do
|
3
3
|
it "should use the last declared matching request stub" do
|
4
4
|
stub_request(:get, "www.example.com").to_return(:body => "abc")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
shared_context "request expectations" do
|
1
|
+
shared_context "request expectations" do |*adapter_info|
|
2
2
|
describe "when request expectations are set" do
|
3
3
|
describe "when net connect is not allowed" do
|
4
4
|
before(:each) do
|
@@ -150,6 +150,13 @@ shared_context "request expectations" do
|
|
150
150
|
a_request(:get, "www.example.com/?x=3").with(:query => {"a" => ["b", "c"]}).should have_been_made
|
151
151
|
}.should_not raise_error
|
152
152
|
end
|
153
|
+
|
154
|
+
it "should satisfy expectation if the request was executed with only part query params declared as a hash in a query option" do
|
155
|
+
lambda {
|
156
|
+
http_request(:get, "http://www.example.com/?a[]=b&a[]=c&b=1")
|
157
|
+
a_request(:get, "www.example.com").with(:query => hash_including({"a" => ["b", "c"]})).should have_been_made
|
158
|
+
}.should_not raise_error
|
159
|
+
end
|
153
160
|
end
|
154
161
|
|
155
162
|
it "should fail if request was made more times than expected" do
|
@@ -209,7 +216,7 @@ shared_context "request expectations" do
|
|
209
216
|
|
210
217
|
describe "when expected reqest body is declared as a hash" do
|
211
218
|
let(:body_hash) { {:a => '1', :b => 'five', 'c' => {'d' => ['e', 'f']}} }
|
212
|
-
let(:fail_message) {%r(The request POST http://www.example.com/ with body
|
219
|
+
let(:fail_message) {%r(The request POST http://www.example.com/ with body .+ was expected to execute 1 time but it executed 0 times)}
|
213
220
|
|
214
221
|
describe "when request is made with url encoded body matching hash" do
|
215
222
|
it "should satisfy expectation" do
|
@@ -290,6 +297,26 @@ shared_context "request expectations" do
|
|
290
297
|
end
|
291
298
|
end
|
292
299
|
|
300
|
+
describe "when expected reqest body is declared as a partial hash matcher" do
|
301
|
+
let(:body_hash) { hash_including({:a => '1', 'c' => {'d' => ['e', 'f']}}) }
|
302
|
+
let(:fail_message) {%r(The request POST http://www.example.com/ with body hash_including(.+) was expected to execute 1 time but it executed 0 times)}
|
303
|
+
|
304
|
+
describe "when request is made with url encoded body matching hash" do
|
305
|
+
it "should satisfy expectation" do
|
306
|
+
lambda {
|
307
|
+
http_request(:post, "http://www.example.com/", :body => 'a=1&c[d][]=e&c[d][]=f&b=five')
|
308
|
+
a_request(:post, "www.example.com").with(:body => body_hash).should have_been_made
|
309
|
+
}.should_not raise_error
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should fail if request is executed with url encoded body not matching hash" do
|
313
|
+
lambda {
|
314
|
+
http_request(:post, "http://www.example.com/", :body => 'c[d][]=f&a=1&c[d][]=e')
|
315
|
+
a_request(:post, "www.example.com").with(:body => body_hash).should have_been_made
|
316
|
+
}.should fail_with(fail_message)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
293
320
|
|
294
321
|
describe "when request with headers is expected" do
|
295
322
|
it "should satisfy expectation if request was executed with the same headers" do
|
@@ -410,7 +437,7 @@ shared_context "request expectations" do
|
|
410
437
|
end
|
411
438
|
end
|
412
439
|
|
413
|
-
describe "with authentication" do
|
440
|
+
describe "with authentication", :unless => (adapter_info.include?(:no_url_auth)) do
|
414
441
|
before(:each) do
|
415
442
|
stub_request(:any, "http://user:pass@www.example.com")
|
416
443
|
stub_request(:any, "http://user:pazz@www.example.com")
|
@@ -541,6 +568,25 @@ shared_context "request expectations" do
|
|
541
568
|
}.should fail_with(%r(The request POST http://www.example.com/ with given block was expected to execute 1 time but it executed 0 times))
|
542
569
|
end
|
543
570
|
end
|
571
|
+
|
572
|
+
describe "when expectation is declared using assert_requested" do
|
573
|
+
it "should satisfy expectation if requests was made" do
|
574
|
+
stub_http = stub_http_request(:get, "http://www.example.com")
|
575
|
+
lambda {
|
576
|
+
http_request(:get, "http://www.example.com/")
|
577
|
+
assert_requested(stub_http, :times => 1)
|
578
|
+
assert_requested(stub_http)
|
579
|
+
}.should_not raise_error
|
580
|
+
end
|
581
|
+
|
582
|
+
it "should fail if request expected not to be made was not wade" do
|
583
|
+
stub_http = stub_http_request(:get, "http://www.example.com")
|
584
|
+
lambda {
|
585
|
+
http_request(:get, "http://www.example.com/")
|
586
|
+
assert_not_requested(stub_http)
|
587
|
+
}.should fail_with(%r(The request GET http://www.example.com/ was expected to execute 0 times but it executed 1 time))
|
588
|
+
end
|
589
|
+
end
|
544
590
|
end
|
545
591
|
|
546
592
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class MyException < StandardError; end;
|
2
2
|
|
3
|
-
shared_context "declared responses" do
|
3
|
+
shared_context "declared responses" do |*adapter_info|
|
4
4
|
describe "when request stub declares that request should raise exception" do
|
5
5
|
it "should raise exception" do
|
6
6
|
stub_request(:get, "www.example.com").to_raise(MyException)
|
@@ -72,13 +72,10 @@ shared_context "declared responses" do
|
|
72
72
|
http_request(:get, "http://www.example.com/").status.should == "500"
|
73
73
|
end
|
74
74
|
|
75
|
-
it "should return response with declared status message" do
|
75
|
+
it "should return response with declared status message", :unless => (adapter_info.include?(:no_status_message)) do
|
76
76
|
stub_request(:get, "www.example.com").to_return(:status => [500, "Internal Server Error"])
|
77
77
|
response = http_request(:get, "http://www.example.com/")
|
78
|
-
|
79
|
-
unless http_library == :em_http_request
|
80
|
-
response.message.should == "Internal Server Error"
|
81
|
-
end
|
78
|
+
response.message.should == "Internal Server Error"
|
82
79
|
end
|
83
80
|
|
84
81
|
it "should return response with a default status code" do
|
@@ -86,13 +83,10 @@ shared_context "declared responses" do
|
|
86
83
|
http_request(:get, "http://www.example.com/").status.should == "200"
|
87
84
|
end
|
88
85
|
|
89
|
-
it "should return default response with empty message if response was not declared" do
|
86
|
+
it "should return default response with empty message if response was not declared", :unless => (adapter_info.include?(:no_status_message)) do
|
90
87
|
stub_request(:get, "www.example.com")
|
91
88
|
response = http_request(:get, "http://www.example.com/")
|
92
|
-
|
93
|
-
unless http_library == :em_http_request
|
94
|
-
response.message.should == ""
|
95
|
-
end
|
89
|
+
response.message.should == ""
|
96
90
|
end
|
97
91
|
|
98
92
|
describe "when response body was declared as IO" do
|
@@ -186,11 +180,8 @@ shared_context "declared responses" do
|
|
186
180
|
@response.status.should == "202"
|
187
181
|
end
|
188
182
|
|
189
|
-
it "should return recorded status message" do
|
190
|
-
|
191
|
-
unless http_library == :em_http_request
|
192
|
-
@response.message.should == "OK"
|
193
|
-
end
|
183
|
+
it "should return recorded status message", :unless => (adapter_info.include?(:no_status_message)) do
|
184
|
+
@response.message.should == "OK"
|
194
185
|
end
|
195
186
|
|
196
187
|
it "should ensure file is closed" do
|
@@ -223,11 +214,8 @@ shared_context "declared responses" do
|
|
223
214
|
@response.status.should == "202"
|
224
215
|
end
|
225
216
|
|
226
|
-
it "should return recorded status message" do
|
227
|
-
|
228
|
-
unless http_library == :em_http_request
|
229
|
-
@response.message.should == "OK"
|
230
|
-
end
|
217
|
+
it "should return recorded status message", :unless => (adapter_info.include?(:no_status_message)) do
|
218
|
+
@response.message.should == "OK"
|
231
219
|
end
|
232
220
|
end
|
233
221
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
shared_examples_for "stubbing requests" do
|
1
|
+
shared_examples_for "stubbing requests" do |*adapter_info|
|
2
2
|
describe "when requests are stubbed" do
|
3
3
|
describe "based on uri" do
|
4
4
|
it "should return stubbed response even if request have escaped parameters" do
|
@@ -32,6 +32,11 @@ shared_examples_for "stubbing requests" do
|
|
32
32
|
stub_request(:get, "www.example.com/?x=3").with(:query => {"a" => ["b", "c"]}).to_return(:body => "abc")
|
33
33
|
http_request(:get, "http://www.example.com/?x=3&a[]=b&a[]=c").body.should == "abc"
|
34
34
|
end
|
35
|
+
|
36
|
+
it "should return stubbed response when stub expects only part of query params" do
|
37
|
+
stub_request(:get, "www.example.com").with(:query => hash_including({"a" => ["b", "c"]})).to_return(:body => "abc")
|
38
|
+
http_request(:get, "http://www.example.com/?a[]=b&a[]=c&b=1").body.should == "abc"
|
39
|
+
end
|
35
40
|
end
|
36
41
|
|
37
42
|
describe "based on method" do
|
@@ -111,7 +116,7 @@ shared_examples_for "stubbing requests" do
|
|
111
116
|
lambda {
|
112
117
|
http_request(
|
113
118
|
:post, "http://www.example.com/",
|
114
|
-
:body => 'c[d][]=f&a=1&c[d][]=e')
|
119
|
+
:body => 'c[d][]=f&a=1&c[d][]=e')
|
115
120
|
}.should raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: POST http://www.example.com/ with body 'c\[d\]\[\]=f&a=1&c\[d\]\[\]=e'))
|
116
121
|
end
|
117
122
|
end
|
@@ -169,6 +174,37 @@ shared_examples_for "stubbing requests" do
|
|
169
174
|
end
|
170
175
|
end
|
171
176
|
end
|
177
|
+
|
178
|
+
describe "when body is declared as partial hash matcher" do
|
179
|
+
before(:each) do
|
180
|
+
stub_request(:post, "www.example.com").
|
181
|
+
with(:body => hash_including({:a => '1', 'c' => {'d' => ['e', 'f']} }))
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "for request with url encoded body" do
|
185
|
+
it "should match request if hash matches body" do
|
186
|
+
http_request(
|
187
|
+
:post, "http://www.example.com/",
|
188
|
+
:body => 'a=1&c[d][]=e&c[d][]=f&b=five').status.should == "200"
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should not match if hash doesn't match url encoded body" do
|
192
|
+
lambda {
|
193
|
+
http_request(
|
194
|
+
:post, "http://www.example.com/",
|
195
|
+
:body => 'c[d][]=f&a=1&c[d][]=e').status
|
196
|
+
}.should raise_error
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "for request with json body and content type is set to json" do
|
201
|
+
it "should match if hash matches body" do
|
202
|
+
http_request(
|
203
|
+
:post, "http://www.example.com/", :headers => {'Content-Type' => 'application/json'},
|
204
|
+
:body => "{\"a\":\"1\",\"c\":{\"d\":[\"e\",\"f\"]},\"b\":\"five\"}").status.should == "200"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
172
208
|
end
|
173
209
|
|
174
210
|
describe "based on headers" do
|
@@ -259,7 +295,7 @@ shared_examples_for "stubbing requests" do
|
|
259
295
|
end
|
260
296
|
end
|
261
297
|
|
262
|
-
describe "when stubbing request with basic authentication" do
|
298
|
+
describe "when stubbing request with basic authentication", :unless => (adapter_info.include?(:no_url_auth)) do
|
263
299
|
it "should match if credentials are the same" do
|
264
300
|
stub_request(:get, "user:pass@www.example.com")
|
265
301
|
http_request(:get, "http://user:pass@www.example.com/").status.should == "200"
|
@@ -289,7 +325,7 @@ shared_examples_for "stubbing requests" do
|
|
289
325
|
|
290
326
|
describe "when stubbing request with a global hook" do
|
291
327
|
after(:each) do
|
292
|
-
WebMock::StubRegistry.instance.
|
328
|
+
WebMock::StubRegistry.instance.global_stubs.clear
|
293
329
|
end
|
294
330
|
|
295
331
|
it 'returns the response returned by the hook' do
|
@@ -335,6 +371,46 @@ shared_examples_for "stubbing requests" do
|
|
335
371
|
http_request(:get, "http://www.example.com/")
|
336
372
|
call_count.should == 1
|
337
373
|
end
|
374
|
+
|
375
|
+
it 'supports multiple global stubs; the first registered one that returns a non-nil value determines the stub' do
|
376
|
+
stub_invocation_order = []
|
377
|
+
WebMock.globally_stub_request do |request|
|
378
|
+
stub_invocation_order << :nil_stub
|
379
|
+
nil
|
380
|
+
end
|
381
|
+
|
382
|
+
WebMock.globally_stub_request do |request|
|
383
|
+
stub_invocation_order << :hash_stub
|
384
|
+
{ :body => "global stub body" }
|
385
|
+
end
|
386
|
+
|
387
|
+
http_request(:get, "http://www.example.com/").body.should == "global stub body"
|
388
|
+
stub_invocation_order.should eq([:nil_stub, :hash_stub])
|
389
|
+
end
|
390
|
+
|
391
|
+
[:before, :after].each do |before_or_after|
|
392
|
+
context "when there is also a non-global registered stub #{before_or_after} the global stub" do
|
393
|
+
def stub_non_globally
|
394
|
+
stub_request(:get, "www.example.com").to_return(:body => 'non-global stub body')
|
395
|
+
end
|
396
|
+
|
397
|
+
define_method :register_stubs do |block|
|
398
|
+
stub_non_globally if before_or_after == :before
|
399
|
+
WebMock.globally_stub_request(&block)
|
400
|
+
stub_non_globally if before_or_after == :after
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'uses the response from the global stub if the block returns a non-nil value' do
|
404
|
+
register_stubs(lambda { |req| { :body => 'global stub body' } })
|
405
|
+
http_request(:get, "http://www.example.com/").body.should == "global stub body"
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'uses the response from the non-global stub if the block returns a nil value' do
|
409
|
+
register_stubs(lambda { |req| nil })
|
410
|
+
http_request(:get, "http://www.example.com/").body.should == "non-global stub body"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
338
414
|
end
|
339
415
|
|
340
416
|
describe "when stubbing request with a block evaluated on request" do
|
@@ -11,7 +11,7 @@ module TyphoeusHydraSpecHelper
|
|
11
11
|
:method => method,
|
12
12
|
:body => options[:body],
|
13
13
|
:headers => options[:headers],
|
14
|
-
:timeout =>
|
14
|
+
:timeout => 25000 # milliseconds
|
15
15
|
}
|
16
16
|
)
|
17
17
|
raise FakeTyphoeusHydraError.new if response.code.to_s == "0"
|
@@ -6,6 +6,7 @@ require 'acceptance/shared/request_expectations'
|
|
6
6
|
require 'acceptance/shared/stubbing_requests'
|
7
7
|
require 'acceptance/shared/allowing_and_disabling_net_connect'
|
8
8
|
require 'acceptance/shared/precedence_of_stubs'
|
9
|
+
require 'acceptance/shared/complex_cross_concern_behaviors'
|
9
10
|
|
10
11
|
unless defined? SAMPLE_HEADERS
|
11
12
|
SAMPLE_HEADERS = { "Content-Length" => "8888", "Accept" => "application/json" }
|
@@ -13,7 +14,7 @@ unless defined? SAMPLE_HEADERS
|
|
13
14
|
NOT_ESCAPED_PARAMS = "z='Stop!' said Fred&x=ab c"
|
14
15
|
end
|
15
16
|
|
16
|
-
shared_examples "with WebMock" do
|
17
|
+
shared_examples "with WebMock" do |*adapter_info|
|
17
18
|
describe "with WebMock" do
|
18
19
|
let(:webmock_server_url) {"http://#{WebMockServer.instance.host_with_port}/"}
|
19
20
|
before(:each) do
|
@@ -21,18 +22,20 @@ shared_examples "with WebMock" do
|
|
21
22
|
WebMock.reset!
|
22
23
|
end
|
23
24
|
|
24
|
-
include_context "allowing and disabling net connect"
|
25
|
+
include_context "allowing and disabling net connect", *adapter_info
|
25
26
|
|
26
|
-
include_context "stubbing requests"
|
27
|
+
include_context "stubbing requests", *adapter_info
|
27
28
|
|
28
|
-
include_context "declared responses"
|
29
|
+
include_context "declared responses", *adapter_info
|
29
30
|
|
30
|
-
include_context "precedence of stubs"
|
31
|
+
include_context "precedence of stubs", *adapter_info
|
31
32
|
|
32
|
-
include_context "request expectations"
|
33
|
+
include_context "request expectations", *adapter_info
|
33
34
|
|
34
|
-
include_context "callbacks"
|
35
|
+
include_context "callbacks", *adapter_info
|
35
36
|
|
36
|
-
include_context "enabled and disabled webmock"
|
37
|
+
include_context "enabled and disabled webmock", *adapter_info
|
38
|
+
|
39
|
+
include_context "complex cross-concern behaviors", *adapter_info
|
37
40
|
end
|
38
41
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -30,11 +30,11 @@ RSpec.configure do |config|
|
|
30
30
|
|
31
31
|
config.filter_run_excluding :without_webmock => true
|
32
32
|
|
33
|
-
config.before(:
|
34
|
-
WebMockServer.instance.start
|
33
|
+
config.before(:suite) do
|
34
|
+
WebMockServer.instance.start unless WebMockServer.instance.started
|
35
35
|
end
|
36
36
|
|
37
|
-
config.after(:
|
37
|
+
config.after(:suite) do
|
38
38
|
WebMockServer.instance.stop
|
39
39
|
end
|
40
40
|
|
data/spec/support/my_rack_app.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
require 'rack'
|
2
2
|
|
3
3
|
class MyRackApp
|
4
|
+
class NonArrayResponse
|
5
|
+
# The rack response body need not implement #join,
|
6
|
+
# but it must implement #each. It need not be an Array.
|
7
|
+
# ActionDispatch::Response, for example, exercises that fact.
|
8
|
+
# See: http://rack.rubyforge.org/doc/SPEC.html
|
9
|
+
|
10
|
+
def each(*args, &blk)
|
11
|
+
["This is not in an array!"].each(*args, &blk)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
def self.call(env)
|
5
16
|
case env.values_at('REQUEST_METHOD', 'PATH_INFO')
|
6
17
|
when ['GET', '/']
|
@@ -8,6 +19,10 @@ class MyRackApp
|
|
8
19
|
when ['GET', '/greet']
|
9
20
|
name = env['QUERY_STRING'][/name=([^&]*)/, 1] || "World"
|
10
21
|
[200, {}, ["Hello, #{name}"]]
|
22
|
+
when ['GET', '/non_array_response']
|
23
|
+
[200, {}, NonArrayResponse.new]
|
24
|
+
when ['GET', '/locked']
|
25
|
+
[200, {}, ["Single threaded response."]]
|
11
26
|
when ['POST', '/greet']
|
12
27
|
name = env["rack.input"].read[/name=([^&]*)/, 1] || "World"
|
13
28
|
[200, {}, ["Good to meet you, #{name}!"]]
|
@@ -15,4 +30,13 @@ class MyRackApp
|
|
15
30
|
[404, {}, ['']]
|
16
31
|
end
|
17
32
|
end
|
18
|
-
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class MyLockedRackApp
|
36
|
+
MUTEX = Mutex.new
|
37
|
+
|
38
|
+
def self.call(env)
|
39
|
+
lock = Rack::Lock.new(MyRackApp, MUTEX)
|
40
|
+
lock.call(env)
|
41
|
+
end
|
42
|
+
end
|