webmock 1.6.4 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/.gitignore +3 -1
- data/.travis.yml +6 -0
- data/CHANGELOG.md +211 -118
- data/Gemfile +16 -1
- data/Guardfile +24 -0
- data/LICENSE +1 -1
- data/README.md +64 -15
- data/Rakefile +19 -6
- data/lib/webmock.rb +9 -4
- data/lib/webmock/api.rb +5 -4
- data/lib/webmock/assertion_failure.rb +1 -1
- data/lib/webmock/callback_registry.rb +1 -1
- data/lib/webmock/config.rb +2 -2
- data/lib/webmock/cucumber.rb +1 -1
- data/lib/webmock/errors.rb +17 -5
- data/lib/webmock/http_lib_adapters/{curb.rb → curb_adapter.rb} +79 -49
- data/lib/webmock/http_lib_adapters/{em_http_request.rb → em_http_request/em_http_request_0_x.rb} +20 -15
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +201 -0
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +11 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
- data/lib/webmock/http_lib_adapters/{httpclient.rb → httpclient_adapter.rb} +35 -8
- data/lib/webmock/http_lib_adapters/net_http.rb +84 -25
- data/lib/webmock/http_lib_adapters/net_http_response.rb +17 -17
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +124 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +166 -0
- data/lib/webmock/minitest.rb +15 -0
- data/lib/webmock/rack_response.rb +52 -0
- data/lib/webmock/request_pattern.rb +4 -2
- data/lib/webmock/request_signature.rb +4 -0
- data/lib/webmock/request_stub.rb +35 -2
- data/lib/webmock/responses_sequence.rb +2 -2
- data/lib/webmock/rspec.rb +2 -2
- data/lib/webmock/rspec/matchers.rb +9 -4
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +1 -1
- data/lib/webmock/stub_registry.rb +1 -1
- data/lib/webmock/stub_request_snippet.rb +14 -11
- data/lib/webmock/util/hash_keys_stringifier.rb +4 -4
- data/lib/webmock/util/headers.rb +3 -3
- data/lib/webmock/util/json.rb +54 -0
- data/lib/webmock/util/uri.rb +1 -1
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +20 -3
- data/minitest/test_helper.rb +29 -0
- data/minitest/test_webmock.rb +6 -0
- data/minitest/webmock_spec.rb +30 -0
- data/spec/curb_spec.rb +26 -8
- data/spec/curb_spec_helper.rb +6 -6
- data/spec/em_http_request_spec.rb +95 -1
- data/spec/em_http_request_spec_helper.rb +16 -16
- data/spec/errors_spec.rb +19 -4
- data/spec/example_curl_output.txt +22 -22
- data/spec/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
- data/spec/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
- data/spec/httpclient_spec.rb +1 -1
- data/spec/httpclient_spec_helper.rb +3 -38
- data/spec/my_rack_app.rb +18 -0
- data/spec/net_http_shared.rb +125 -0
- data/spec/net_http_spec.rb +27 -31
- data/spec/net_http_spec_helper.rb +4 -34
- data/spec/network_connection.rb +1 -1
- data/spec/patron_spec_helper.rb +4 -7
- data/spec/quality_spec.rb +60 -0
- data/spec/rack_response_spec.rb +33 -0
- data/spec/real_net_http_spec.rb +20 -0
- data/spec/request_execution_verifier_spec.rb +8 -8
- data/spec/request_pattern_spec.rb +3 -3
- data/spec/request_stub_spec.rb +19 -19
- data/spec/response_spec.rb +8 -8
- data/spec/spec_helper.rb +14 -11
- data/spec/stub_request_snippet_spec.rb +85 -37
- data/spec/support/webmock_server.rb +62 -0
- data/spec/typhoeus_hydra_spec.rb +53 -0
- data/spec/typhoeus_hydra_spec_helper.rb +50 -0
- data/spec/util/headers_spec.rb +5 -5
- data/spec/util/json_spec.rb +7 -0
- data/spec/util/uri_spec.rb +1 -1
- data/spec/vendor/addressable/lib/uri.rb +1 -0
- data/spec/vendor/crack/lib/crack.rb +1 -0
- data/spec/vendor/right_http_connection-1.2.4/History.txt +4 -4
- data/spec/vendor/right_http_connection-1.2.4/README.txt +4 -4
- data/spec/vendor/right_http_connection-1.2.4/Rakefile +3 -3
- data/spec/vendor/right_http_connection-1.2.4/lib/net_fix.rb +4 -4
- data/spec/vendor/right_http_connection-1.2.4/setup.rb +4 -4
- data/spec/webmock_shared.rb +375 -143
- data/spec/webmock_spec.rb +7 -0
- data/test/http_request.rb +24 -0
- data/test/shared_test.rb +47 -0
- data/test/test_helper.rb +6 -3
- data/test/test_webmock.rb +2 -67
- data/webmock.gemspec +8 -7
- metadata +153 -88
- data/lib/webmock/http_lib_adapters/patron.rb +0 -100
- data/spec/other_net_http_libs_spec.rb +0 -30
data/spec/curb_spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module CurbSpecHelper
|
2
4
|
def http_request(method, uri, options = {}, &block)
|
3
5
|
uri = Addressable::URI.heuristic_parse(uri)
|
@@ -5,7 +7,8 @@ module CurbSpecHelper
|
|
5
7
|
|
6
8
|
curl = curb_http_request(uri, method, body, options)
|
7
9
|
|
8
|
-
status, response_headers =
|
10
|
+
status, response_headers =
|
11
|
+
WebMock::HttpLibAdapters::CurbAdapter.parse_header_string(curl.header_str)
|
9
12
|
|
10
13
|
OpenStruct.new(
|
11
14
|
:body => curl.body_str,
|
@@ -17,7 +20,7 @@ module CurbSpecHelper
|
|
17
20
|
|
18
21
|
def setup_request(uri, curl, options={})
|
19
22
|
curl ||= Curl::Easy.new
|
20
|
-
curl.url = uri.omit(:userinfo).to_s
|
23
|
+
curl.url = uri.omit(:userinfo).to_s
|
21
24
|
curl.username = uri.user
|
22
25
|
curl.password = uri.password
|
23
26
|
curl.timeout = 10
|
@@ -38,9 +41,6 @@ module CurbSpecHelper
|
|
38
41
|
Curl::Err::ConnectionFailedError
|
39
42
|
end
|
40
43
|
|
41
|
-
def setup_expectations_for_real_request(options = {})
|
42
|
-
end
|
43
|
-
|
44
44
|
def http_library
|
45
45
|
:curb
|
46
46
|
end
|
@@ -54,7 +54,7 @@ module CurbSpecHelper
|
|
54
54
|
curl.post_body = body
|
55
55
|
when :put
|
56
56
|
curl.put_data = body
|
57
|
-
end
|
57
|
+
end
|
58
58
|
|
59
59
|
curl.http(method)
|
60
60
|
curl
|
@@ -10,6 +10,97 @@ unless RUBY_PLATFORM =~ /java/
|
|
10
10
|
|
11
11
|
it_should_behave_like "WebMock"
|
12
12
|
|
13
|
+
#functionality only supported for em-http-request 1.x
|
14
|
+
if defined?(EventMachine::HttpConnection)
|
15
|
+
describe "with middleware" do
|
16
|
+
|
17
|
+
it "should work with request middleware" do
|
18
|
+
stub_http_request(:get, "www.example.com").with(:body => 'bar')
|
19
|
+
|
20
|
+
middleware = Class.new do
|
21
|
+
def request(client, head, body)
|
22
|
+
[{}, 'bar']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
EM.run do
|
27
|
+
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
28
|
+
|
29
|
+
conn.use middleware
|
30
|
+
|
31
|
+
http = conn.get(:body => 'foo')
|
32
|
+
|
33
|
+
http.callback do
|
34
|
+
WebMock.should have_requested(:get, "www.example.com").with(:body => 'bar')
|
35
|
+
EM.stop
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should work with response middleware" do
|
41
|
+
stub_http_request(:get, "www.example.com").to_return(:body => 'foo')
|
42
|
+
|
43
|
+
middleware = Class.new do
|
44
|
+
def response(resp)
|
45
|
+
resp.response = 'bar'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
EM.run do
|
50
|
+
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
51
|
+
|
52
|
+
conn.use middleware
|
53
|
+
|
54
|
+
http = conn.get
|
55
|
+
|
56
|
+
http.callback do
|
57
|
+
http.response.should be == 'bar'
|
58
|
+
EM.stop
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# not pretty, but it works
|
65
|
+
describe "with synchrony" do
|
66
|
+
let(:webmock_em_http) { File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb")) }
|
67
|
+
|
68
|
+
before(:each) do
|
69
|
+
# need to reload the webmock em-http adapter after we require synchrony
|
70
|
+
WebMock::HttpLibAdapters::EmHttpRequestAdapter.disable!
|
71
|
+
$".delete webmock_em_http
|
72
|
+
$".delete File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
73
|
+
require 'em-synchrony'
|
74
|
+
require 'em-synchrony/em-http'
|
75
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should work" do
|
79
|
+
stub_request(:post, /.*.testserver.com*/).to_return(:status => 200, :body => 'ok')
|
80
|
+
lambda {
|
81
|
+
EM.run do
|
82
|
+
fiber = Fiber.new do
|
83
|
+
http = EM::HttpRequest.new("http://www.testserver.com").post :body => "foo=bar&baz=bang", :timeout => 60
|
84
|
+
EM.stop
|
85
|
+
end
|
86
|
+
fiber.resume
|
87
|
+
end
|
88
|
+
}.should_not raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
after(:each) do
|
92
|
+
EM.send(:remove_const, :Synchrony)
|
93
|
+
EM.send(:remove_const, :HTTPMethods)
|
94
|
+
WebMock::HttpLibAdapters::EmHttpRequestAdapter.disable!
|
95
|
+
$".reject! {|path| path.include? "em-http-request"}
|
96
|
+
$".delete webmock_em_http
|
97
|
+
$".delete File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
98
|
+
require 'em-http-request'
|
99
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
13
104
|
it "should work with streaming" do
|
14
105
|
stub_http_request(:get, "www.example.com").to_return(:body => "abc")
|
15
106
|
response = ""
|
@@ -36,7 +127,10 @@ unless RUBY_PLATFORM =~ /java/
|
|
36
127
|
end
|
37
128
|
|
38
129
|
describe "mocking EM::HttpClient API" do
|
39
|
-
before
|
130
|
+
before do
|
131
|
+
stub_http_request(:get, "www.example.com/")
|
132
|
+
WebMock::HttpLibAdapters::EmHttpRequestAdapter.enable!
|
133
|
+
end
|
40
134
|
subject do
|
41
135
|
client = nil
|
42
136
|
EM.run do
|
@@ -6,34 +6,37 @@ module EMHttpRequestSpecHelper
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def http_request(method, uri, options = {}, &block)
|
9
|
+
@http = nil
|
10
|
+
head = options[:headers] || {}
|
9
11
|
response = nil
|
10
12
|
error = nil
|
11
13
|
uri = Addressable::URI.heuristic_parse(uri)
|
12
14
|
EventMachine.run {
|
13
|
-
request = EventMachine::HttpRequest.new("#{uri.
|
14
|
-
http = request.send(
|
15
|
-
:timeout => 10,
|
15
|
+
request = EventMachine::HttpRequest.new("#{uri.normalize.to_s}")
|
16
|
+
http = request.send(method, {
|
17
|
+
:timeout => 10,
|
16
18
|
:body => options[:body],
|
17
19
|
:query => options[:query],
|
18
|
-
'authorization' => [uri.user, uri.password]
|
19
|
-
|
20
|
+
:head => head.merge('authorization' => [uri.user, uri.password])
|
21
|
+
}, &block)
|
20
22
|
http.errback {
|
21
23
|
error = if http.respond_to?(:errors)
|
22
|
-
http.errors
|
24
|
+
http.errors
|
23
25
|
else
|
24
26
|
http.error
|
25
|
-
end
|
26
|
-
failed
|
27
|
+
end
|
28
|
+
failed
|
27
29
|
}
|
28
|
-
http.callback {
|
30
|
+
http.callback {
|
29
31
|
response = OpenStruct.new({
|
30
32
|
:body => http.response,
|
31
|
-
:headers => WebMock::Util::Headers.normalize_headers(extract_response_headers(http)),
|
33
|
+
:headers => WebMock::Util::Headers.normalize_headers(extract_response_headers(http)),
|
32
34
|
:message => http.response_header.http_reason,
|
33
35
|
:status => http.response_header.status.to_s
|
34
36
|
})
|
35
37
|
EventMachine.stop
|
36
38
|
}
|
39
|
+
@http = http
|
37
40
|
}
|
38
41
|
raise error if error
|
39
42
|
response
|
@@ -47,21 +50,18 @@ module EMHttpRequestSpecHelper
|
|
47
50
|
""
|
48
51
|
end
|
49
52
|
|
50
|
-
def setup_expectations_for_real_request(options = {})
|
51
|
-
end
|
52
|
-
|
53
53
|
def http_library
|
54
54
|
:em_http_request
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
private
|
58
|
-
|
58
|
+
|
59
59
|
def extract_response_headers(http)
|
60
60
|
headers = {}
|
61
61
|
if http.response_header
|
62
62
|
http.response_header.each do |k,v|
|
63
63
|
v = v.join(", ") if v.is_a?(Array)
|
64
|
-
headers[k] = v
|
64
|
+
headers[k] = v
|
65
65
|
end
|
66
66
|
end
|
67
67
|
headers
|
data/spec/errors_spec.rb
CHANGED
@@ -5,13 +5,28 @@ describe "errors" do
|
|
5
5
|
describe "message" do
|
6
6
|
it "should have message with request signature and snippet" do
|
7
7
|
request_signature = mock(:to_s => "aaa")
|
8
|
+
request_stub = mock
|
9
|
+
WebMock::RequestStub.stub!(:from_request_signature).and_return(request_stub)
|
8
10
|
WebMock::StubRequestSnippet.stub!(:new).
|
9
|
-
with(
|
11
|
+
with(request_stub).and_return(mock(:to_s => "bbb"))
|
10
12
|
expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
|
11
13
|
"\n\nYou can stub this request with the following snippet:\n\n" +
|
12
|
-
"bbb\n\n============================================================"
|
13
|
-
WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
|
14
|
+
"bbb\n\n============================================================"
|
15
|
+
WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have message with registered stubs if available" do
|
19
|
+
request_signature = mock(:to_s => "aaa")
|
20
|
+
request_stub = mock
|
21
|
+
WebMock::StubRegistry.instance.stub!(:request_stubs).and_return([request_stub])
|
22
|
+
WebMock::RequestStub.stub!(:from_request_signature).and_return(request_stub)
|
23
|
+
WebMock::StubRequestSnippet.stub!(:new).
|
24
|
+
with(request_stub).and_return(mock(:to_s => "bbb"))
|
25
|
+
expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
|
26
|
+
"\n\nYou can stub this request with the following snippet:\n\n" +
|
27
|
+
"bbb\n\nregistered request stubs:\n\nbbb\n\n============================================================"
|
28
|
+
WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
|
14
29
|
end
|
15
30
|
end
|
16
31
|
end
|
17
|
-
end
|
32
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
HTTP/1.1 202 OK
|
2
|
-
Content-Type: text/html; charset=UTF-8
|
3
|
-
Connection: Keep-Alive
|
4
|
-
Date: Sat, 23 Jan 2010 01:01:05 GMT
|
5
|
-
Content-Length:
|
6
|
-
Accept: image/jpeg
|
7
|
-
Accept: image/png
|
8
|
-
|
9
|
-
<HTML>
|
10
|
-
<HEAD>
|
11
|
-
<TITLE>Example Web Page</TITLE>
|
12
|
-
</HEAD>
|
13
|
-
<body>
|
14
|
-
<p>You have reached this web page by typing "example.com",
|
15
|
-
"example.net",
|
16
|
-
or "example.org" into your web browser.</p>
|
17
|
-
<p>These domain names are reserved for use in documentation and are not available
|
18
|
-
for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC
|
19
|
-
2606</a>, Section 3.</p>
|
20
|
-
</BODY>
|
21
|
-
</HTML>
|
22
|
-
|
1
|
+
HTTP/1.1 202 OK
|
2
|
+
Content-Type: text/html; charset=UTF-8
|
3
|
+
Connection: Keep-Alive
|
4
|
+
Date: Sat, 23 Jan 2010 01:01:05 GMT
|
5
|
+
Content-Length: 419
|
6
|
+
Accept: image/jpeg
|
7
|
+
Accept: image/png
|
8
|
+
|
9
|
+
<HTML>
|
10
|
+
<HEAD>
|
11
|
+
<TITLE>Example Web Page</TITLE>
|
12
|
+
</HEAD>
|
13
|
+
<body>
|
14
|
+
<p>You have reached this web page by typing "example.com",
|
15
|
+
"example.net",
|
16
|
+
or "example.org" into your web browser.</p>
|
17
|
+
<p>These domain names are reserved for use in documentation and are not available
|
18
|
+
for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC
|
19
|
+
2606</a>, Section 3.</p>
|
20
|
+
</BODY>
|
21
|
+
</HTML>
|
22
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe WebMock::HttpLibAdapterRegistry do
|
4
|
+
describe "each_adapter" do
|
5
|
+
it "should yield block over each adapter" do
|
6
|
+
class MyAdapter < WebMock::HttpLibAdapter; end
|
7
|
+
WebMock::HttpLibAdapterRegistry.instance.register(:my_lib, MyAdapter)
|
8
|
+
adapters = []
|
9
|
+
WebMock::HttpLibAdapterRegistry.instance.each_adapter {|n,a|
|
10
|
+
adapters << [n, a]
|
11
|
+
}
|
12
|
+
adapters.should include([:my_lib, MyAdapter])
|
13
|
+
WebMock::HttpLibAdapterRegistry.instance.
|
14
|
+
http_lib_adapters.delete(:my_lib)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe WebMock::HttpLibAdapter do
|
4
|
+
describe "adapter_for" do
|
5
|
+
it "should add adapter to adapter registry" do
|
6
|
+
class MyAdapter < WebMock::HttpLibAdapter; end
|
7
|
+
WebMock::HttpLibAdapterRegistry.instance.
|
8
|
+
should_receive(:register).with(:my_lib, MyAdapter)
|
9
|
+
MyAdapter.adapter_for(:my_lib)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/spec/httpclient_spec.rb
CHANGED
@@ -2,7 +2,7 @@ module HTTPClientSpecHelper
|
|
2
2
|
class << self
|
3
3
|
attr_accessor :async_mode
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
def http_request(method, uri, options = {}, &block)
|
7
7
|
uri = Addressable::URI.heuristic_parse(uri)
|
8
8
|
c = HTTPClient.new
|
@@ -17,7 +17,7 @@ module HTTPClientSpecHelper
|
|
17
17
|
else
|
18
18
|
response = c.request(*params, &block)
|
19
19
|
end
|
20
|
-
headers = response.header.all.inject({}) do |headers, header|
|
20
|
+
headers = response.header.all.inject({}) do |headers, header|
|
21
21
|
if !headers.has_key?(header[0])
|
22
22
|
headers[header[0]] = header[1]
|
23
23
|
else
|
@@ -41,43 +41,8 @@ module HTTPClientSpecHelper
|
|
41
41
|
Errno::ECONNREFUSED
|
42
42
|
end
|
43
43
|
|
44
|
-
def setup_expectations_for_real_request(options = {})
|
45
|
-
socket = mock("TCPSocket")
|
46
|
-
TCPSocket.should_receive(:new).
|
47
|
-
with(options[:host], options[:port]).at_least(:once).and_return(socket)
|
48
|
-
|
49
|
-
socket.stub!(:closed?).and_return(false)
|
50
|
-
socket.stub!(:close).and_return(true)
|
51
|
-
|
52
|
-
request_parts = ["#{options[:method]} #{options[:path]} HTTP/1.1", "Host: #{options[:host]}"]
|
53
|
-
|
54
|
-
if options[:port] == 443
|
55
|
-
OpenSSL::SSL::SSLSocket.should_receive(:new).
|
56
|
-
with(socket, instance_of(OpenSSL::SSL::SSLContext)).
|
57
|
-
at_least(:once).and_return(socket = mock("SSLSocket"))
|
58
|
-
socket.should_receive(:connect).at_least(:once).with()
|
59
|
-
socket.should_receive(:peer_cert).and_return(mock('peer cert', :extensions => []))
|
60
|
-
socket.should_receive(:write).with(/#{request_parts[0]}.*#{request_parts[1]}.*/m).and_return(100)
|
61
|
-
else
|
62
|
-
socket.should_receive(:<<).with(/#{request_parts[0]}.*#{request_parts[1]}.*/m).and_return(100)
|
63
|
-
end
|
64
|
-
|
65
|
-
socket.stub!(:sync=).with(true)
|
66
|
-
|
67
|
-
socket.should_receive(:gets).with("\n").
|
68
|
-
and_return("HTTP/1.1 #{options[:response_code]} #{options[:response_message]}\r\n",
|
69
|
-
"Content-Length: #{options[:response_body].length}\r\n",
|
70
|
-
"\r\n")
|
71
|
-
socket.stub(:readpartial) do |size, buf|
|
72
|
-
buf << options[:response_body]
|
73
|
-
end
|
74
|
-
|
75
|
-
socket.stub!(:eof?).and_return(true)
|
76
|
-
socket.stub!(:close).and_return(true)
|
77
|
-
end
|
78
|
-
|
79
44
|
def http_library
|
80
|
-
:
|
45
|
+
:httpclient
|
81
46
|
end
|
82
47
|
|
83
48
|
end
|
data/spec/my_rack_app.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
class MyRackApp
|
4
|
+
def self.call(env)
|
5
|
+
case env.values_at('REQUEST_METHOD', 'PATH_INFO')
|
6
|
+
when ['GET', '/']
|
7
|
+
[200, {}, ["This is my root!"]]
|
8
|
+
when ['GET', '/greet']
|
9
|
+
name = env['QUERY_STRING'][/name=([^&]*)/, 1] || "World"
|
10
|
+
[200, {}, ["Hello, #{name}"]]
|
11
|
+
when ['POST', '/greet']
|
12
|
+
name = env["rack.input"].read[/name=([^&]*)/, 1] || "World"
|
13
|
+
[200, {}, ["Good to meet you, #{name}!"]]
|
14
|
+
else
|
15
|
+
[404, {}, ['']]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
shared_examples_for "Net::HTTP" do
|
2
|
+
describe "when making real requests", :net_connect => true do
|
3
|
+
let(:port){ WebMockServer.instance.port }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@http = Net::HTTP.new("localhost", port)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return a Net::ReadAdapter from response.body when a real request is made with a block and #read_body", :net_connect => true do
|
10
|
+
response = Net::HTTP.new("localhost", port).request_get('/') { |r| r.read_body { } }
|
11
|
+
response.body.should be_a(Net::ReadAdapter)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should handle requests with block passed to read_body", :net_connect => true do
|
15
|
+
body = ""
|
16
|
+
req = Net::HTTP::Get.new("/")
|
17
|
+
Net::HTTP.start("localhost", port) do |http|
|
18
|
+
http.request(req) do |res|
|
19
|
+
res.read_body do |str|
|
20
|
+
body << str
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
body.should =~ /hello world/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should connect only once when connected on start", :net_connect => true do
|
28
|
+
@http = Net::HTTP.new('localhost', port)
|
29
|
+
socket_id_before_request = socket_id_after_request = nil
|
30
|
+
@http.start {|conn|
|
31
|
+
socket_id_before_request = conn.instance_variable_get(:@socket).object_id
|
32
|
+
conn.request(Net::HTTP::Get.new("/"))
|
33
|
+
socket_id_after_request = conn.instance_variable_get(:@socket).object_id
|
34
|
+
}
|
35
|
+
socket_id_after_request.should_not be_nil
|
36
|
+
socket_id_after_request.should == socket_id_before_request
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "without start" do
|
40
|
+
it "should close connection after a real request" do
|
41
|
+
@http.get('/') { }
|
42
|
+
@http.should_not be_started
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should execute block exactly once" do
|
46
|
+
times = 0
|
47
|
+
@http.get('/') { times += 1 }
|
48
|
+
times.should == 1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have socket open during a real request" do
|
52
|
+
socket_id = nil
|
53
|
+
@http.get('/') {
|
54
|
+
socket_id = @http.instance_variable_get(:@socket).object_id
|
55
|
+
}
|
56
|
+
socket_id.should_not be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be started during a real request" do
|
60
|
+
started = nil
|
61
|
+
@http.get('/') {
|
62
|
+
started = @http.started?
|
63
|
+
}
|
64
|
+
started.should == true
|
65
|
+
@http.started?.should == false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "with start" do
|
70
|
+
it "should close connection after a real request" do
|
71
|
+
@http.start {|conn| conn.get('/') { } }
|
72
|
+
@http.should_not be_started
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should execute block exactly once" do
|
76
|
+
times = 0
|
77
|
+
@http.start {|conn| conn.get('/') { times += 1 }}
|
78
|
+
times.should == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have socket open during a real request" do
|
82
|
+
socket_id = nil
|
83
|
+
@http.start {|conn| conn.get('/') {
|
84
|
+
socket_id = conn.instance_variable_get(:@socket).object_id
|
85
|
+
}
|
86
|
+
}
|
87
|
+
socket_id.should_not be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be started during a real request" do
|
91
|
+
started = nil
|
92
|
+
@http.start {|conn| conn.get('/') {
|
93
|
+
started = conn.started?
|
94
|
+
}
|
95
|
+
}
|
96
|
+
started.should == true
|
97
|
+
@http.started?.should == false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "with start without request block" do
|
102
|
+
it "should close connection after a real request" do
|
103
|
+
@http.start {|conn| conn.get('/') }
|
104
|
+
@http.should_not be_started
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should have socket open during a real request" do
|
108
|
+
socket_id = nil
|
109
|
+
@http.start {|conn|
|
110
|
+
socket_id = conn.instance_variable_get(:@socket).object_id
|
111
|
+
}
|
112
|
+
socket_id.should_not be_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be started during a real request" do
|
116
|
+
started = nil
|
117
|
+
@http.start {|conn|
|
118
|
+
started = conn.started?
|
119
|
+
}
|
120
|
+
started.should == true
|
121
|
+
@http.started?.should == false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|