webmock 1.8.6 → 3.14.0

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 (138) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/CI.yml +37 -0
  3. data/.gitignore +6 -0
  4. data/CHANGELOG.md +1198 -0
  5. data/Gemfile +3 -15
  6. data/README.md +761 -305
  7. data/Rakefile +13 -40
  8. data/lib/webmock/api.rb +63 -17
  9. data/lib/webmock/callback_registry.rb +1 -1
  10. data/lib/webmock/config.rb +8 -0
  11. data/lib/webmock/cucumber.rb +2 -0
  12. data/lib/webmock/errors.rb +8 -24
  13. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
  14. data/lib/webmock/http_lib_adapters/curb_adapter.rb +148 -84
  15. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +224 -4
  16. data/lib/webmock/http_lib_adapters/excon_adapter.rb +104 -34
  17. data/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
  18. data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  19. data/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
  20. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  21. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  22. data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  23. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +152 -86
  24. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
  25. data/lib/webmock/http_lib_adapters/net_http.rb +155 -46
  26. data/lib/webmock/http_lib_adapters/net_http_response.rb +1 -1
  27. data/lib/webmock/http_lib_adapters/patron_adapter.rb +16 -15
  28. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +76 -82
  29. data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  30. data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  31. data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  32. data/lib/webmock/matchers/hash_including_matcher.rb +4 -12
  33. data/lib/webmock/minitest.rb +29 -3
  34. data/lib/webmock/rack_response.rb +14 -7
  35. data/lib/webmock/request_body_diff.rb +64 -0
  36. data/lib/webmock/request_execution_verifier.rb +38 -17
  37. data/lib/webmock/request_pattern.rb +158 -38
  38. data/lib/webmock/request_registry.rb +3 -3
  39. data/lib/webmock/request_signature.rb +7 -3
  40. data/lib/webmock/request_signature_snippet.rb +61 -0
  41. data/lib/webmock/request_stub.rb +9 -6
  42. data/lib/webmock/response.rb +30 -15
  43. data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +38 -2
  44. data/lib/webmock/rspec/matchers/webmock_matcher.rb +23 -2
  45. data/lib/webmock/rspec/matchers.rb +0 -1
  46. data/lib/webmock/rspec.rb +11 -2
  47. data/lib/webmock/stub_registry.rb +31 -10
  48. data/lib/webmock/stub_request_snippet.rb +14 -6
  49. data/lib/webmock/test_unit.rb +4 -4
  50. data/lib/webmock/util/hash_counter.rb +20 -6
  51. data/lib/webmock/util/hash_keys_stringifier.rb +5 -3
  52. data/lib/webmock/util/hash_validator.rb +17 -0
  53. data/lib/webmock/util/headers.rb +23 -2
  54. data/lib/webmock/util/json.rb +20 -7
  55. data/lib/webmock/util/query_mapper.rb +281 -0
  56. data/lib/webmock/util/uri.rb +29 -19
  57. data/lib/webmock/util/values_stringifier.rb +20 -0
  58. data/lib/webmock/util/version_checker.rb +40 -2
  59. data/lib/webmock/version.rb +1 -1
  60. data/lib/webmock/webmock.rb +56 -17
  61. data/lib/webmock.rb +56 -46
  62. data/minitest/test_helper.rb +8 -3
  63. data/minitest/test_webmock.rb +4 -1
  64. data/minitest/webmock_spec.rb +16 -6
  65. data/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
  66. data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  67. data/spec/acceptance/curb/curb_spec.rb +227 -68
  68. data/spec/acceptance/curb/curb_spec_helper.rb +11 -8
  69. data/spec/acceptance/em_http_request/em_http_request_spec.rb +322 -28
  70. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +15 -10
  71. data/spec/acceptance/excon/excon_spec.rb +66 -4
  72. data/spec/acceptance/excon/excon_spec_helper.rb +21 -7
  73. data/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
  74. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  75. data/spec/acceptance/httpclient/httpclient_spec.rb +152 -11
  76. data/spec/acceptance/httpclient/httpclient_spec_helper.rb +25 -16
  77. data/spec/acceptance/manticore/manticore_spec.rb +107 -0
  78. data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  79. data/spec/acceptance/net_http/net_http_shared.rb +52 -24
  80. data/spec/acceptance/net_http/net_http_spec.rb +164 -50
  81. data/spec/acceptance/net_http/net_http_spec_helper.rb +19 -10
  82. data/spec/acceptance/net_http/real_net_http_spec.rb +1 -1
  83. data/spec/acceptance/patron/patron_spec.rb +29 -40
  84. data/spec/acceptance/patron/patron_spec_helper.rb +15 -11
  85. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +229 -58
  86. data/spec/acceptance/shared/callbacks.rb +32 -30
  87. data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +20 -5
  88. data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +14 -14
  89. data/spec/acceptance/shared/precedence_of_stubs.rb +6 -6
  90. data/spec/acceptance/shared/request_expectations.rb +560 -296
  91. data/spec/acceptance/shared/returning_declared_responses.rb +180 -138
  92. data/spec/acceptance/shared/stubbing_requests.rb +385 -154
  93. data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +78 -17
  94. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +19 -15
  95. data/spec/acceptance/webmock_shared.rb +2 -2
  96. data/spec/fixtures/test.txt +1 -0
  97. data/spec/quality_spec.rb +27 -3
  98. data/spec/spec_helper.rb +11 -20
  99. data/spec/support/failures.rb +9 -0
  100. data/spec/support/my_rack_app.rb +8 -3
  101. data/spec/support/network_connection.rb +7 -13
  102. data/spec/support/webmock_server.rb +8 -3
  103. data/spec/unit/api_spec.rb +175 -0
  104. data/spec/unit/errors_spec.rb +116 -19
  105. data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +1 -1
  106. data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +2 -2
  107. data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  108. data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  109. data/spec/unit/rack_response_spec.rb +54 -16
  110. data/spec/unit/request_body_diff_spec.rb +90 -0
  111. data/spec/unit/request_execution_verifier_spec.rb +147 -39
  112. data/spec/unit/request_pattern_spec.rb +462 -198
  113. data/spec/unit/request_registry_spec.rb +29 -9
  114. data/spec/unit/request_signature_snippet_spec.rb +89 -0
  115. data/spec/unit/request_signature_spec.rb +91 -49
  116. data/spec/unit/request_stub_spec.rb +71 -70
  117. data/spec/unit/response_spec.rb +100 -81
  118. data/spec/unit/stub_registry_spec.rb +37 -20
  119. data/spec/unit/stub_request_snippet_spec.rb +51 -31
  120. data/spec/unit/util/hash_counter_spec.rb +6 -6
  121. data/spec/unit/util/hash_keys_stringifier_spec.rb +4 -4
  122. data/spec/unit/util/headers_spec.rb +4 -4
  123. data/spec/unit/util/json_spec.rb +29 -3
  124. data/spec/unit/util/query_mapper_spec.rb +157 -0
  125. data/spec/unit/util/uri_spec.rb +150 -36
  126. data/spec/unit/util/version_checker_spec.rb +15 -9
  127. data/spec/unit/webmock_spec.rb +57 -4
  128. data/test/http_request.rb +3 -3
  129. data/test/shared_test.rb +45 -13
  130. data/test/test_helper.rb +1 -1
  131. data/test/test_webmock.rb +6 -0
  132. data/webmock.gemspec +30 -11
  133. metadata +308 -199
  134. data/.rvmrc +0 -1
  135. data/.travis.yml +0 -11
  136. data/Guardfile +0 -24
  137. data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_0_x.rb +0 -151
  138. data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +0 -210
@@ -1,18 +1,18 @@
1
1
  shared_examples_for "Net::HTTP" do
2
- describe "when making real requests", :net_connect => true do
2
+ describe "when making real requests", net_connect: true do
3
3
  let(:port){ WebMockServer.instance.port }
4
4
 
5
5
  before(:each) do
6
6
  @http = Net::HTTP.new("localhost", port)
7
7
  end
8
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
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
10
  response = Net::HTTP.new("localhost", port).request_get('/') { |r| r.read_body { } }
11
- response.body.should be_a(Net::ReadAdapter)
11
+ expect(response.body).to be_a(Net::ReadAdapter)
12
12
  end
13
13
 
14
- it "should handle requests with block passed to read_body", :net_connect => true do
15
- body = ""
14
+ it "should handle requests with block passed to read_body", net_connect: true do
15
+ body = "".dup
16
16
  req = Net::HTTP::Get.new("/")
17
17
  Net::HTTP.start("localhost", port) do |http|
18
18
  http.request(req) do |res|
@@ -21,10 +21,10 @@ shared_examples_for "Net::HTTP" do
21
21
  end
22
22
  end
23
23
  end
24
- body.should =~ /hello world/
24
+ expect(body).to match(/hello world/)
25
25
  end
26
26
 
27
- it "should connect only once when connected on start", :net_connect => true do
27
+ it "should connect only once when connected on start", net_connect: true do
28
28
  @http = Net::HTTP.new('localhost', port)
29
29
  socket_id_before_request = socket_id_after_request = nil
30
30
  @http.start {|conn|
@@ -32,20 +32,38 @@ shared_examples_for "Net::HTTP" do
32
32
  conn.request(Net::HTTP::Get.new("/"))
33
33
  socket_id_after_request = conn.instance_variable_get(:@socket).object_id
34
34
  }
35
- socket_id_after_request.should_not be_nil
36
- socket_id_after_request.should == socket_id_before_request
35
+
36
+ if !defined?(WebMock::Config) || WebMock::Config.instance.net_http_connect_on_start
37
+ expect(socket_id_before_request).not_to eq(nil.object_id)
38
+ expect(socket_id_after_request).not_to eq(nil.object_id)
39
+ expect(socket_id_after_request).to eq(socket_id_before_request)
40
+ else
41
+ expect(socket_id_before_request).to eq(nil.object_id)
42
+ expect(socket_id_after_request).not_to eq(nil.object_id)
43
+ end
44
+ end
45
+
46
+ it "should pass the read_timeout value on", net_connect: true do
47
+ @http = Net::HTTP.new('localhost', port)
48
+ read_timeout = @http.read_timeout + 1
49
+ @http.read_timeout = read_timeout
50
+ @http.start {|conn|
51
+ conn.request(Net::HTTP::Get.new("/"))
52
+ socket = conn.instance_variable_get(:@socket)
53
+ expect(socket.read_timeout).to eq(read_timeout)
54
+ }
37
55
  end
38
56
 
39
57
  describe "without start" do
40
58
  it "should close connection after a real request" do
41
59
  @http.get('/') { }
42
- @http.should_not be_started
60
+ expect(@http).not_to be_started
43
61
  end
44
62
 
45
63
  it "should execute block exactly once" do
46
64
  times = 0
47
65
  @http.get('/') { times += 1 }
48
- times.should == 1
66
+ expect(times).to eq(1)
49
67
  end
50
68
 
51
69
  it "should have socket open during a real request" do
@@ -53,7 +71,7 @@ shared_examples_for "Net::HTTP" do
53
71
  @http.get('/') {
54
72
  socket_id = @http.instance_variable_get(:@socket).object_id
55
73
  }
56
- socket_id.should_not be_nil
74
+ expect(socket_id).not_to be_nil
57
75
  end
58
76
 
59
77
  it "should be started during a real request" do
@@ -61,21 +79,21 @@ shared_examples_for "Net::HTTP" do
61
79
  @http.get('/') {
62
80
  started = @http.started?
63
81
  }
64
- started.should == true
65
- @http.started?.should == false
82
+ expect(started).to eq(true)
83
+ expect(@http.started?).to eq(false)
66
84
  end
67
85
  end
68
86
 
69
87
  describe "with start" do
70
88
  it "should close connection after a real request" do
71
89
  @http.start {|conn| conn.get('/') { } }
72
- @http.should_not be_started
90
+ expect(@http).not_to be_started
73
91
  end
74
92
 
75
93
  it "should execute block exactly once" do
76
94
  times = 0
77
95
  @http.start {|conn| conn.get('/') { times += 1 }}
78
- times.should == 1
96
+ expect(times).to eq(1)
79
97
  end
80
98
 
81
99
  it "should have socket open during a real request" do
@@ -84,7 +102,7 @@ shared_examples_for "Net::HTTP" do
84
102
  socket_id = conn.instance_variable_get(:@socket).object_id
85
103
  }
86
104
  }
87
- socket_id.should_not be_nil
105
+ expect(socket_id).not_to be_nil
88
106
  end
89
107
 
90
108
  it "should be started during a real request" do
@@ -93,15 +111,15 @@ shared_examples_for "Net::HTTP" do
93
111
  started = conn.started?
94
112
  }
95
113
  }
96
- started.should == true
97
- @http.started?.should == false
114
+ expect(started).to eq(true)
115
+ expect(@http.started?).to eq(false)
98
116
  end
99
117
  end
100
118
 
101
119
  describe "with start without request block" do
102
120
  it "should close connection after a real request" do
103
121
  @http.start {|conn| conn.get('/') }
104
- @http.should_not be_started
122
+ expect(@http).not_to be_started
105
123
  end
106
124
 
107
125
  it "should have socket open during a real request" do
@@ -109,7 +127,7 @@ shared_examples_for "Net::HTTP" do
109
127
  @http.start {|conn|
110
128
  socket_id = conn.instance_variable_get(:@socket).object_id
111
129
  }
112
- socket_id.should_not be_nil
130
+ expect(socket_id).not_to be_nil
113
131
  end
114
132
 
115
133
  it "should be started during a real request" do
@@ -117,9 +135,19 @@ shared_examples_for "Net::HTTP" do
117
135
  @http.start {|conn|
118
136
  started = conn.started?
119
137
  }
120
- started.should == true
121
- @http.started?.should == false
138
+ expect(started).to eq(true)
139
+ expect(@http.started?).to eq(false)
140
+ end
141
+ end
142
+
143
+ describe "with start without a block and finish" do
144
+ it "should gracefully start and close connection" do
145
+ @http.start
146
+ @http.get("/")
147
+ expect(@http).to be_started
148
+ @http.finish
149
+ expect(@http).not_to be_started
122
150
  end
123
151
  end
124
152
  end
125
- end
153
+ end
@@ -7,9 +7,9 @@ require 'acceptance/net_http/net_http_shared'
7
7
  include NetHTTPSpecHelper
8
8
 
9
9
  describe "Net:HTTP" do
10
- include_examples "with WebMock"
10
+ include_examples "with WebMock", :no_url_auth
11
11
 
12
- let(:port){ WebMockServer.instance.port }
12
+ let(:port) { WebMockServer.instance.port }
13
13
 
14
14
  describe "marshalling" do
15
15
  class TestMarshalingInWebMockNetHTTP
@@ -58,91 +58,159 @@ describe "Net:HTTP" do
58
58
 
59
59
  describe "constants" do
60
60
  it "should still have const Get defined on replaced Net::HTTP" do
61
- Object.const_get("Net").const_get("HTTP").const_defined?("Get").should be_true
61
+ expect(Object.const_get("Net").const_get("HTTP").const_defined?("Get")).to be_truthy
62
62
  end
63
63
 
64
64
  it "should still have const Get within constants on replaced Net::HTTP" do
65
- Object.const_get("Net").const_get("HTTP").constants.map(&:to_s).should include("Get")
65
+ expect(Object.const_get("Net").const_get("HTTP").constants.map(&:to_s)).to include("Get")
66
66
  end
67
67
 
68
68
  it "should still have const Get within constants on replaced Net::HTTP" do
69
- Object.const_get("Net").const_get("HTTP").const_get("Get").should_not be_nil
69
+ expect(Object.const_get("Net").const_get("HTTP").const_get("Get")).not_to be_nil
70
70
  end
71
71
 
72
72
  if Module.method(:const_defined?).arity != 1
73
73
  it "should still have const Get defined (and not inherited) on replaced Net::HTTP" do
74
- Object.const_get("Net").const_get("HTTP").const_defined?("Get", false).should be_true
74
+ expect(Object.const_get("Net").const_get("HTTP").const_defined?("Get", false)).to be_truthy
75
75
  end
76
76
  end
77
77
 
78
78
  if Module.method(:const_get).arity != 1
79
79
  it "should still be able to get non inherited constant Get on replaced Net::HTTP" do
80
- Object.const_get("Net").const_get("HTTP").const_get("Get", false).should_not be_nil
80
+ expect(Object.const_get("Net").const_get("HTTP").const_get("Get", false)).not_to be_nil
81
81
  end
82
82
  end
83
83
 
84
84
  if Module.method(:constants).arity != 0
85
85
  it "should still Get within non inherited constants on replaced Net::HTTP" do
86
- Object.const_get("Net").const_get("HTTP").constants(false).map(&:to_s).should include("Get")
86
+ expect(Object.const_get("Net").const_get("HTTP").constants(false).map(&:to_s)).to include("Get")
87
+ end
88
+ end
89
+
90
+ describe "after WebMock is disabled" do
91
+ after(:each) do
92
+ WebMock.enable!
93
+ end
94
+ it "Net::HTTP should have the same constants" do
95
+ orig_consts_number = WebMock::HttpLibAdapters::NetHttpAdapter::OriginalNetHTTP.constants.size
96
+ Net::HTTP.send(:const_set, "TEST_CONST", 10)
97
+ expect(Net::HTTP.constants.size).to eq(orig_consts_number + 1)
98
+ WebMock.disable!
99
+ expect(Net::HTTP.constants.size).to eq(orig_consts_number + 1)
87
100
  end
88
101
  end
89
102
  end
90
103
 
91
104
  it "should work with block provided" do
92
- stub_http_request(:get, "www.example.com").to_return(:body => "abc"*100000)
93
- Net::HTTP.start("www.example.com") { |query| query.get("/") }.body.should == "abc"*100000
105
+ stub_http_request(:get, "www.example.com").to_return(body: "abc"*100000)
106
+ expect(Net::HTTP.start("www.example.com") { |query| query.get("/") }.body).to eq("abc"*100000)
107
+ end
108
+
109
+ it "should handle requests with raw binary data" do
110
+ body = "\x14\x00\x00\x00\x70\x69\x6e\x67\x00\x00"
111
+ stub_http_request(:post, "www.example.com").with(body: body).to_return(body: "abc")
112
+ req = Net::HTTP::Post.new("/")
113
+ req.body = body
114
+ req.content_type = "application/octet-stream"
115
+ expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
116
+ end
117
+
118
+ it "raises an ArgumentError if passed headers as symbols if RUBY_VERSION < 2.3.0" do
119
+ uri = URI.parse("http://google.com/")
120
+ http = Net::HTTP.new(uri.host, uri.port)
121
+ request = Net::HTTP::Get.new(uri.request_uri)
122
+
123
+ # Net::HTTP calls downcase on header keys assigned with []=
124
+ # In Ruby 1.8.7 symbols do not respond to downcase
125
+ #
126
+ # Meaning you can not assign header keys as symbols in ruby 1.8.7 using []=
127
+ if :symbol.respond_to?(:downcase)
128
+ request[:InvalidHeaderSinceItsASymbol] = "this will not be valid"
129
+ else
130
+ request.instance_eval do
131
+ @header = request.to_hash.merge({InvalidHeaderSinceItsASymbol: "this will not be valid"})
132
+ end
133
+ end
134
+
135
+ if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
136
+ expect do
137
+ http.request(request)
138
+ end.to raise_error ArgumentError, "Net:HTTP does not accept headers as symbols"
139
+ else
140
+ stub_http_request(:get, "google.com").with(headers: { InvalidHeaderSinceItsASymbol: "this will not be valid" })
141
+ expect do
142
+ http.request(request)
143
+ end.not_to raise_error
144
+ end
94
145
  end
95
146
 
96
147
  it "should handle multiple values for the same response header" do
97
- stub_http_request(:get, "www.example.com").to_return(:headers => { 'Set-Cookie' => ['foo=bar', 'bar=bazz'] })
148
+ stub_http_request(:get, "www.example.com").to_return(headers: { 'Set-Cookie' => ['foo=bar', 'bar=bazz'] })
98
149
  response = Net::HTTP.get_response(URI.parse("http://www.example.com/"))
99
- response.get_fields('Set-Cookie').should == ['bar=bazz', 'foo=bar']
150
+ expect(response.get_fields('Set-Cookie')).to eq(['bar=bazz', 'foo=bar'])
100
151
  end
101
152
 
102
153
  it "should yield block on response" do
103
- stub_http_request(:get, "www.example.com").to_return(:body => "abc")
154
+ stub_http_request(:get, "www.example.com").to_return(body: "abc")
104
155
  response_body = ""
105
156
  http_request(:get, "http://www.example.com/") do |response|
106
157
  response_body = response.body
107
158
  end
108
- response_body.should == "abc"
159
+ expect(response_body).to eq("abc")
109
160
  end
110
161
 
111
162
  it "should handle Net::HTTP::Post#body" do
112
- stub_http_request(:post, "www.example.com").with(:body => "my_params").to_return(:body => "abc")
163
+ stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
113
164
  req = Net::HTTP::Post.new("/")
114
165
  req.body = "my_params"
115
- Net::HTTP.start("www.example.com") { |http| http.request(req)}.body.should == "abc"
166
+ expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
116
167
  end
117
168
 
118
169
  it "should handle Net::HTTP::Post#body_stream" do
119
- stub_http_request(:post, "www.example.com").with(:body => "my_params").to_return(:body => "abc")
170
+ stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
120
171
  req = Net::HTTP::Post.new("/")
121
172
  req.body_stream = StringIO.new("my_params")
122
- Net::HTTP.start("www.example.com") { |http| http.request(req)}.body.should == "abc"
173
+ expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
123
174
  end
124
175
 
125
176
  it "should behave like Net::HTTP and raise error if both request body and body argument are set" do
126
- stub_http_request(:post, "www.example.com").with(:body => "my_params").to_return(:body => "abc")
177
+ stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
127
178
  req = Net::HTTP::Post.new("/")
128
179
  req.body = "my_params"
129
- lambda {
180
+ expect {
130
181
  Net::HTTP.start("www.example.com") { |http| http.request(req, "my_params")}
131
- }.should raise_error("both of body argument and HTTPRequest#body set")
182
+ }.to raise_error("both of body argument and HTTPRequest#body set")
132
183
  end
133
184
 
134
185
  it "should return a Net::ReadAdapter from response.body when a stubbed request is made with a block and #read_body" do
135
- WebMock.stub_request(:get, 'http://example.com/').to_return(:body => "the body")
186
+ WebMock.stub_request(:get, 'http://example.com/').to_return(body: "the body")
136
187
  response = Net::HTTP.new('example.com', 80).request_get('/') { |r| r.read_body { } }
137
- response.body.should be_a(Net::ReadAdapter)
188
+ expect(response.body).to be_a(Net::ReadAdapter)
138
189
  end
139
190
 
140
- it "should have request 1 time executed in registry after 1 real request", :net_connect => true do
191
+ it "should have request 1 time executed in registry after 1 real request", net_connect: true do
141
192
  WebMock.allow_net_connect!
142
193
  http = Net::HTTP.new('localhost', port)
143
194
  http.get('/') {}
144
- WebMock::RequestRegistry.instance.requested_signatures.hash.size.should == 1
145
- WebMock::RequestRegistry.instance.requested_signatures.hash.values.first.should == 1
195
+ expect(WebMock::RequestRegistry.instance.requested_signatures.hash.size).to eq(1)
196
+ expect(WebMock::RequestRegistry.instance.requested_signatures.hash.values.first).to eq(1)
197
+ end
198
+
199
+ it "should work with Addressable::URI passed to Net::HTTP.get_response" do
200
+ stub_request(:get, 'http://www.example.com/hello?a=1').to_return(body: "abc")
201
+ expect(Net::HTTP.get_response(Addressable::URI.parse('http://www.example.com/hello?a=1')).body).to eq("abc")
202
+ end
203
+
204
+ it "should support method calls on stubbed socket" do
205
+ WebMock.allow_net_connect!
206
+ stub_request(:get, 'www.google.com')#.with(headers: {"My-Header" => 99})
207
+ req = Net::HTTP::Get.new('/')
208
+ Net::HTTP.start('www.google.com') do |http|
209
+ http.request(req, '')
210
+ socket = http.instance_variable_get(:@socket)
211
+ expect(socket).to be_a(StubSocket)
212
+ expect { socket.io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) }.to_not raise_error
213
+ end
146
214
  end
147
215
 
148
216
  describe "connecting on Net::HTTP.start" do
@@ -151,43 +219,49 @@ describe "Net:HTTP" do
151
219
  @http.use_ssl = true
152
220
  @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
153
221
  end
222
+
154
223
  describe "when net http is allowed" do
155
- it "should not connect to the server until the request", :net_connect => true do
224
+ it "should not connect to the server until the request", net_connect: true do
156
225
  WebMock.allow_net_connect!
157
226
  @http.start {|conn|
158
- conn.peer_cert.should be_nil
227
+ expect(conn.peer_cert).to be_nil
159
228
  }
160
229
  end
161
230
 
162
- it "should connect to the server on start", :net_connect => true do
163
- WebMock.allow_net_connect!(:net_http_connect_on_start => true)
231
+ it "should connect to the server on start", net_connect: true do
232
+ WebMock.allow_net_connect!(net_http_connect_on_start: true)
164
233
  @http.start {|conn|
165
234
  cert = OpenSSL::X509::Certificate.new conn.peer_cert
166
- cert.should be_a(OpenSSL::X509::Certificate)
235
+ expect(cert).to be_a(OpenSSL::X509::Certificate)
167
236
  }
168
237
  end
169
238
 
170
239
  end
171
240
 
172
241
  describe "when net http is disabled and allowed only for some hosts" do
173
- it "should not connect to the server until the request", :net_connect => true do
174
- WebMock.disable_net_connect!(:allow => "www.google.com")
242
+ it "should not connect to the server until the request", net_connect: true do
243
+ WebMock.disable_net_connect!(allow: "www.google.com")
175
244
  @http.start {|conn|
176
- conn.peer_cert.should be_nil
245
+ expect(conn.peer_cert).to be_nil
177
246
  }
178
247
  end
179
248
 
180
- it "should connect to the server on start", :net_connect => true do
181
- WebMock.disable_net_connect!(:allow => "www.google.com", :net_http_connect_on_start => true)
249
+ it "should connect to the server on start", net_connect: true do
250
+ WebMock.disable_net_connect!(allow: "www.google.com", net_http_connect_on_start: true)
182
251
  @http.start {|conn|
183
252
  cert = OpenSSL::X509::Certificate.new conn.peer_cert
184
- cert.should be_a(OpenSSL::X509::Certificate)
253
+ expect(cert).to be_a(OpenSSL::X509::Certificate)
185
254
  }
186
255
  end
187
256
 
188
- it "should connect to the server if the URI matches an regex", :net_connect => true do
189
- WebMock.disable_net_connect!(:allow => /google.com/)
190
- response = Net::HTTP.get('www.google.com','/')
257
+ it "should connect to the server if the URI matches an regex", net_connect: true do
258
+ WebMock.disable_net_connect!(allow: /google.com/)
259
+ Net::HTTP.get('www.google.com','/')
260
+ end
261
+
262
+ it "should connect to the server if the URI matches any regex the array", net_connect: true do
263
+ WebMock.disable_net_connect!(allow: [/google.com/, /yahoo.com/])
264
+ Net::HTTP.get('www.google.com','/')
191
265
  end
192
266
 
193
267
  end
@@ -196,19 +270,19 @@ describe "Net:HTTP" do
196
270
 
197
271
  describe "when net_http_connect_on_start is true" do
198
272
  before(:each) do
199
- WebMock.allow_net_connect!(:net_http_connect_on_start => true)
273
+ WebMock.allow_net_connect!(net_http_connect_on_start: true)
200
274
  end
201
275
  it_should_behave_like "Net::HTTP"
202
276
  end
203
277
 
204
278
  describe "when net_http_connect_on_start is false" do
205
279
  before(:each) do
206
- WebMock.allow_net_connect!(:net_http_connect_on_start => false)
280
+ WebMock.allow_net_connect!(net_http_connect_on_start: false)
207
281
  end
208
282
  it_should_behave_like "Net::HTTP"
209
283
  end
210
284
 
211
- describe 'after_request callback support', :net_connect => true do
285
+ describe 'after_request callback support', net_connect: true do
212
286
  let(:expected_body_regex) { /hello world/ }
213
287
 
214
288
  before(:each) do
@@ -231,25 +305,65 @@ describe "Net:HTTP" do
231
305
  end
232
306
 
233
307
  it "should support the after_request callback on an request with block and read_body" do
234
- response_body = ''
308
+ response_body = ''.dup
235
309
  http_request(:get, "http://localhost:#{port}/") do |response|
236
310
  response.read_body { |fragment| response_body << fragment }
237
311
  end
238
- response_body.should =~ expected_body_regex
312
+ expect(response_body).to match(expected_body_regex)
239
313
 
240
- @callback_response.body.should == response_body
314
+ expect(@callback_response.body).to eq(response_body)
241
315
  end
242
316
 
243
317
  it "should support the after_request callback on a request with a returning block" do
244
318
  response_body = perform_get_with_returning_block
245
- response_body.should =~ expected_body_regex
246
- @callback_response.should be_instance_of(WebMock::Response)
247
- @callback_response.body.should == response_body
319
+ expect(response_body).to match(expected_body_regex)
320
+ expect(@callback_response).to be_instance_of(WebMock::Response)
321
+ expect(@callback_response.body).to eq(response_body)
248
322
  end
249
323
 
250
324
  it "should only invoke the after_request callback once, even for a recursive post request" do
251
325
  Net::HTTP.new('localhost', port).post('/', nil)
252
- @callback_invocation_count.should == 1
326
+ expect(@callback_invocation_count).to eq(1)
327
+ end
328
+ end
329
+
330
+ it "should match http headers, even if their values have been set in a request as numbers" do
331
+ WebMock.disable_net_connect!
332
+
333
+ stub_request(:post, "www.example.com").with(headers: {"My-Header" => 99})
334
+
335
+ uri = URI.parse('http://www.example.com/')
336
+ req = Net::HTTP::Post.new(uri.path)
337
+ req['My-Header'] = 99
338
+
339
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
340
+ http.request(req, '')
341
+ end
342
+ end
343
+
344
+ describe "hostname handling" do
345
+ it "should set brackets around the hostname if it is an IPv6 address" do
346
+ net_http = Net::HTTP.new('b2dc:5bdf:4f0d::3014:e0ca', 80)
347
+ path = '/example.jpg'
348
+ expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
349
+ end
350
+
351
+ it "should not set brackets around the hostname if it is already wrapped by brackets" do
352
+ net_http = Net::HTTP.new('[b2dc:5bdf:4f0d::3014:e0ca]', 80)
353
+ path = '/example.jpg'
354
+ expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
355
+ end
356
+
357
+ it "should not set brackets around the hostname if it is an IPv4 address" do
358
+ net_http = Net::HTTP.new('181.152.137.168', 80)
359
+ path = '/example.jpg'
360
+ expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://181.152.137.168:80/example.jpg')
361
+ end
362
+
363
+ it "should not set brackets around the hostname if it is a domain" do
364
+ net_http = Net::HTTP.new('www.example.com', 80)
365
+ path = '/example.jpg'
366
+ expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://www.example.com:80/example.jpg')
253
367
  end
254
368
  end
255
369
  end
@@ -10,15 +10,18 @@ module NetHTTPSpecHelper
10
10
  req = clazz.new("#{uri.path}#{uri.query ? '?' : ''}#{uri.query}", nil)
11
11
  options[:headers].each do |k,v|
12
12
  if v.is_a?(Array)
13
- v.each_with_index do |v,i|
14
- i == 0 ? (req[k] = v) : req.add_field(k, v)
13
+ v.each_with_index do |e,i|
14
+ i == 0 ? (req[k] = e) : req.add_field(k, e)
15
15
  end
16
16
  else
17
17
  req[k] = v
18
18
  end
19
19
  end if options[:headers]
20
20
 
21
- req.basic_auth uri.user, uri.password if uri.user
21
+ if options[:basic_auth]
22
+ req.basic_auth(options[:basic_auth][0], options[:basic_auth][1])
23
+ end
24
+
22
25
  http = Net::HTTP.new(uri.host, uri.port)
23
26
  if uri.scheme == "https"
24
27
  http.use_ssl = true
@@ -28,21 +31,27 @@ module NetHTTPSpecHelper
28
31
  http.read_timeout = 60
29
32
  end
30
33
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
31
- response = http.start {|http|
32
- http.request(req, options[:body], &block)
34
+ response = http.start {|open_http|
35
+ open_http.request(req, options[:body], &block)
33
36
  }
34
37
  headers = {}
35
38
  response.each_header {|name, value| headers[name] = value}
36
39
  OpenStruct.new({
37
- :body => response.body,
38
- :headers => WebMock::Util::Headers.normalize_headers(headers),
39
- :status => response.code,
40
- :message => response.message
40
+ body: response.body,
41
+ headers: WebMock::Util::Headers.normalize_headers(headers),
42
+ status: response.code,
43
+ message: response.message
41
44
  })
42
45
  end
43
46
 
44
47
  def client_timeout_exception_class
45
- Timeout::Error
48
+ if defined?(Net::OpenTimeout)
49
+ Net::OpenTimeout
50
+ elsif defined?(Net::HTTP::OpenTimeout)
51
+ Net::HTTP::OpenTimeout
52
+ else
53
+ Timeout::Error
54
+ end
46
55
  end
47
56
 
48
57
  def connection_refused_exception_class
@@ -6,7 +6,7 @@ require 'stringio'
6
6
  require 'acceptance/net_http/net_http_shared'
7
7
  require 'support/webmock_server'
8
8
 
9
- describe "Real Net:HTTP without webmock", :without_webmock => true do
9
+ describe "Real Net:HTTP without webmock", without_webmock: true do
10
10
  before(:all) do
11
11
  raise "WebMock has no access here!!!" if defined?(WebMock::NetHTTPUtility)
12
12
  WebMockServer.instance.start