webmock 1.3.5 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,28 @@
1
1
  #Changelog
2
2
 
3
+ ## 1.4.0
4
+
5
+ * Curb support!!! Thanks to the awesome work of Pete Higgins!
6
+
7
+ * `include WebMock` is now deprecated to avoid method and constant name conflicts. Please `include WebMock::API` instead.
8
+
9
+ * `WebMock::API#request` is renamed to `WebMock::API#a_request` to prevent method name conflicts with i.e. Rails controller specs.
10
+ WebMock.request is still available.
11
+
12
+ * Deprecated `WebMock#request`, `WebMock#allow_net_connect!`, `WebMock#net_connect_allowed?`, `WebMock#registered_request?`, `WebMock#reset_callbacks`, `WebMock#after_request` instance methods. These methods are still available, but only as WebMock class methods.
13
+
14
+ * Removed `WebMock.response_for_request` and `WebMock.assertion_failure` which were only used internally and were not documented.
15
+
16
+ * :allow_localhost => true' now permits 0.0.0.0 in addition to 127.0.0.1 and 'localhost'. Thanks to Myron Marston and Mike Gehard for suggesting this.
17
+
18
+ * Fixed issue with both RSpec 1.x and 2.x being available.
19
+
20
+ WebMock now tries to use already loaded version of RSpec (1.x or 2.x). Previously it was loading RSpec 2.0 if available, even if RSpec 1.3 was already loaded.
21
+
22
+ Thanks to Hans de Graaff for reporting this.
23
+
24
+ * Changed runtime dependency on Addressable version 2.2.2 which fixes handling of percent-escaped '+'
25
+
3
26
  ## 1.3.5
4
27
 
5
28
  * External requests can be disabled while allowing selected hosts. Thanks to Charles Li and Ryan Bigg
data/README.md CHANGED
@@ -21,6 +21,7 @@ Supported HTTP libraries
21
21
  * HTTPClient
22
22
  * Patron
23
23
  * EM-HTTP-Request
24
+ * Curb
24
25
 
25
26
  ##Installation
26
27
 
@@ -33,7 +34,7 @@ Add the following code to `test/test_helper.rb`
33
34
  require 'webmock/test_unit'
34
35
 
35
36
  class Test::Unit::TestCase
36
- config.include WebMock
37
+ include WebMock::API
37
38
  end
38
39
 
39
40
  ### RSpec
@@ -43,7 +44,7 @@ Add the following code to `spec/spec_helper`:
43
44
  require 'webmock/rspec'
44
45
 
45
46
  Spec::Runner.configure do |config|
46
- config.include WebMock
47
+ config.include WebMock::API
47
48
  end
48
49
 
49
50
  ### RSpec 2
@@ -53,25 +54,20 @@ Add the following code to `spec/spec_helper`:
53
54
  require 'webmock/rspec'
54
55
 
55
56
  RSpec.configure do |config|
56
- config.include WebMock
57
+ config.include WebMock::API
57
58
  end
58
59
 
59
60
  ### Cucumber
60
61
 
61
62
  Add the following code to `features/support/env.rb`
62
63
 
63
- require 'webmock/rspec'
64
- module WebMockWorld
65
- include WebMock
66
- include WebMock::Matchers
67
- end
68
-
69
- World(WebMockWorld)
64
+ require 'webmock/rspec'
65
+ World(WebMock::API, WebMock::Matchers)
70
66
 
71
67
  You can also use WebMock outside a test framework:
72
68
 
73
69
  require 'webmock'
74
- include WebMock
70
+ include WebMock::API
75
71
  include WebMock::Matchers
76
72
 
77
73
  ## Examples
@@ -357,19 +353,19 @@ You can also use WebMock outside a test framework:
357
353
 
358
354
  ### Different way of setting expectations in RSpec
359
355
 
360
- request(:post, "www.example.com").with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
356
+ a_request(:post, "www.example.com").with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
361
357
 
362
- request(:post, "www.something.com").should have_been_made.times(3)
358
+ a_request(:post, "www.something.com").should have_been_made.times(3)
363
359
 
364
- request(:any, "www.example.com").should_not have_been_made
360
+ a_request(:any, "www.example.com").should_not have_been_made
365
361
 
366
- request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
367
-
368
- request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}).should have_been_made
369
-
370
- request(:post, "www.example.com").
362
+ a_request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
363
+
364
+ a_request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}).should have_been_made
365
+
366
+ a_request(:post, "www.example.com").
371
367
  with(:body => {"a" => ["b", "c"]}, :headers => 'Content-Type' => 'application/json').should have_been_made
372
-
368
+
373
369
  ## Clearing stubs and request history
374
370
 
375
371
  If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
@@ -535,6 +531,7 @@ People who submitted patches and new features or suggested improvements. Many th
535
531
  * Muness Alrubaie
536
532
  * Charles Li
537
533
  * Ryan Bigg
534
+ * Pete Higgins
538
535
 
539
536
  ## Background
540
537
 
data/Rakefile CHANGED
@@ -10,12 +10,13 @@ begin
10
10
  gem.email = "bartosz.blimke@gmail.com"
11
11
  gem.homepage = "http://github.com/bblimke/webmock"
12
12
  gem.authors = ["Bartosz Blimke"]
13
- gem.add_dependency "addressable", ">= 2.1.1"
13
+ gem.add_dependency "addressable", ">= 2.2.2"
14
14
  gem.add_dependency "crack", ">=0.1.7"
15
15
  gem.add_development_dependency "rspec", ">= 1.2.9"
16
16
  gem.add_development_dependency "httpclient", ">= 2.1.5.2"
17
- gem.add_development_dependency "patron", ">= 0.4.5" unless RUBY_PLATFORM =~ /java/
18
- gem.add_development_dependency "em-http-request", ">= 0.2.7" unless RUBY_PLATFORM =~ /java/
17
+ gem.add_development_dependency "patron", ">= 0.4.9" unless RUBY_PLATFORM =~ /java/
18
+ gem.add_development_dependency "em-http-request", ">= 0.2.14" unless RUBY_PLATFORM =~ /java/
19
+ gem.add_development_dependency "curb", ">= 0.7.8" unless RUBY_PLATFORM =~ /java/
19
20
  end
20
21
  Jeweler::GemcutterTasks.new
21
22
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.5
1
+ 1.4.0
@@ -3,9 +3,12 @@ require 'singleton'
3
3
  require 'addressable/uri'
4
4
  require 'crack'
5
5
 
6
+ require 'webmock/deprecation'
7
+
6
8
  require 'webmock/http_lib_adapters/net_http'
7
9
  require 'webmock/http_lib_adapters/httpclient'
8
10
  require 'webmock/http_lib_adapters/patron'
11
+ require 'webmock/http_lib_adapters/curb'
9
12
  require 'webmock/http_lib_adapters/em_http_request'
10
13
 
11
14
  require 'webmock/errors'
@@ -20,8 +23,10 @@ require 'webmock/responses_sequence'
20
23
  require 'webmock/request_stub'
21
24
  require 'webmock/response'
22
25
 
26
+ require 'webmock/assertion_failure'
23
27
  require 'webmock/request_execution_verifier'
24
28
  require 'webmock/config'
25
29
  require 'webmock/callback_registry'
26
30
  require 'webmock/request_registry'
31
+ require 'webmock/api'
27
32
  require 'webmock/webmock'
@@ -1,13 +1,20 @@
1
1
  require 'webmock'
2
2
 
3
3
  # RSpec 1.x and 2.x compatibility
4
- begin
5
- require 'rspec'
4
+ if defined?(Rspec)
6
5
  RSPEC_NAMESPACE = RSPEC_CONFIGURER = Rspec
7
- rescue LoadError
8
- require 'spec'
6
+ elsif defined?(Spec)
9
7
  RSPEC_NAMESPACE = Spec
10
8
  RSPEC_CONFIGURER = Spec::Runner
9
+ else
10
+ begin
11
+ require 'rspec'
12
+ RSPEC_NAMESPACE = RSPEC_CONFIGURER = Rspec
13
+ rescue LoadError
14
+ require 'spec'
15
+ RSPEC_NAMESPACE = Spec
16
+ RSPEC_CONFIGURER = Spec::Runner
17
+ end
11
18
  end
12
19
 
13
20
  require 'webmock/adapters/rspec/request_pattern_matcher'
@@ -23,8 +30,4 @@ RSPEC_CONFIGURER.configure { |config|
23
30
  end
24
31
  }
25
32
 
26
- module WebMock
27
- def assertion_failure(message)
28
- raise RSPEC_NAMESPACE::Expectations::ExpectationNotMetError.new(message)
29
- end
30
- end
33
+ WebMock::AssertionFailure.error_class = RSPEC_NAMESPACE::Expectations::ExpectationNotMetError
@@ -15,10 +15,5 @@ class Test::Unit::TestCase
15
15
  end
16
16
  end
17
17
 
18
- module WebMock
19
- AssertionFailedError = Test::Unit::AssertionFailedError rescue MiniTest::Assertion # ruby1.9 compat
20
- def assertion_failure(message)
21
- raise AssertionFailedError.new(message)
22
- end
23
- end
24
18
 
19
+ WebMock::AssertionFailure.error_class = Test::Unit::AssertionFailedError rescue MiniTest::Assertion # ruby1.9 compat
@@ -0,0 +1,32 @@
1
+ module WebMock
2
+ module API
3
+ extend self
4
+
5
+ def stub_request(method, uri)
6
+ WebMock::RequestRegistry.instance.register_request_stub(WebMock::RequestStub.new(method, uri))
7
+ end
8
+
9
+ alias_method :stub_http_request, :stub_request
10
+
11
+ def a_request(method, uri)
12
+ WebMock::RequestPattern.new(method, uri)
13
+ end
14
+
15
+ class << self
16
+ alias :request :a_request
17
+ end
18
+
19
+ def assert_requested(method, uri, options = {}, &block)
20
+ expected_times_executed = options.delete(:times) || 1
21
+ request = WebMock::RequestPattern.new(method, uri, options).with(&block)
22
+ verifier = WebMock::RequestExecutionVerifier.new(request, expected_times_executed)
23
+ WebMock::AssertionFailure.failure(verifier.failure_message) unless verifier.matches?
24
+ end
25
+
26
+ def assert_not_requested(method, uri, options = {}, &block)
27
+ request = WebMock::RequestPattern.new(method, uri, options).with(&block)
28
+ verifier = WebMock::RequestExecutionVerifier.new(request, options.delete(:times))
29
+ WebMock::AssertionFailure.failure(verifier.negative_failure_message) unless verifier.does_not_match?
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ module WebMock
2
+ class AssertionFailure
3
+ class << self
4
+ attr_writer :error_class
5
+ @error_class = RuntimeError
6
+
7
+ def failure(message)
8
+ raise @error_class.new(message)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module WebMock
2
+ class Deprecation
3
+ class << self
4
+ def warning(message)
5
+ warn "WebMock deprecation warning: #{message}"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,260 @@
1
+ if defined?(Curl)
2
+
3
+ module Curl
4
+ class Easy
5
+ def curb_or_webmock
6
+ request_signature = build_request_signature
7
+ WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
8
+
9
+ if WebMock::RequestRegistry.instance.registered_request?(request_signature)
10
+ webmock_response = WebMock::RequestRegistry.instance.response_for_request(request_signature)
11
+ build_curb_response(webmock_response)
12
+ WebMock::CallbackRegistry.invoke_callbacks(
13
+ {:lib => :curb}, request_signature, webmock_response)
14
+ invoke_curb_callbacks
15
+ true
16
+ elsif WebMock.net_connect_allowed?(request_signature.uri)
17
+ res = yield
18
+ if WebMock::CallbackRegistry.any_callbacks?
19
+ webmock_response = build_webmock_response
20
+ WebMock::CallbackRegistry.invoke_callbacks(
21
+ {:lib => :curb, :real_request => true}, request_signature,
22
+ webmock_response)
23
+ end
24
+ res
25
+ else
26
+ raise WebMock::NetConnectNotAllowedError.new(request_signature)
27
+ end
28
+ end
29
+
30
+ def build_request_signature
31
+ method = @webmock_method.to_s.downcase.to_sym
32
+
33
+ uri = WebMock::Util::URI.heuristic_parse(self.url)
34
+ uri.path = uri.normalized_path.gsub("[^:]//","/")
35
+ uri.user = self.username
36
+ uri.password = self.password
37
+
38
+ request_body = case method
39
+ when :post
40
+ self.post_body || @post_body
41
+ when :put
42
+ @put_data
43
+ else
44
+ nil
45
+ end
46
+
47
+ request_signature = WebMock::RequestSignature.new(
48
+ method,
49
+ uri.to_s,
50
+ :body => request_body,
51
+ :headers => self.headers
52
+ )
53
+ request_signature
54
+ end
55
+
56
+ def build_curb_response(webmock_response)
57
+ raise Curl::Err::TimeoutError if webmock_response.should_timeout
58
+ webmock_response.raise_error_if_any
59
+
60
+ @body_str = webmock_response.body
61
+ @response_code = webmock_response.status[0]
62
+
63
+ @header_str = "HTTP/1.1 #{webmock_response.status[0]} #{webmock_response.status[1]}\r\n"
64
+ if webmock_response.headers
65
+ @header_str << webmock_response.headers.map do |k,v|
66
+ "#{k}: #{v.is_a?(Array) ? v.join(", ") : v}"
67
+ end.join("\r\n")
68
+ end
69
+ end
70
+
71
+ def invoke_curb_callbacks
72
+ @on_progress.call(0.0,1.0,0.0,1.0) if @on_progress
73
+ @on_header.call(self.header_str) if @on_header
74
+ @on_body.call(self.body_str) if @on_body
75
+ @on_complete.call(self) if @on_complete
76
+
77
+ case response_code
78
+ when 200..299
79
+ @on_success.call(self) if @on_success
80
+ when 500..599
81
+ @on_failure.call(self, self.response_code) if @on_failure
82
+ end
83
+ end
84
+
85
+ def build_webmock_response
86
+ status, headers = WebmockHelper.parse_header_string(self.header_str)
87
+
88
+ webmock_response = WebMock::Response.new
89
+ webmock_response.status = [self.response_code, status]
90
+ webmock_response.body = self.body_str
91
+ webmock_response.headers = headers
92
+ webmock_response
93
+ end
94
+
95
+ ###
96
+ ### Mocks of Curl::Easy methods below here.
97
+ ###
98
+
99
+ def http_with_webmock(method)
100
+ @webmock_method = method
101
+ curb_or_webmock do
102
+ http_without_webmock(method)
103
+ end
104
+ end
105
+ alias_method :http_without_webmock, :http
106
+ alias_method :http, :http_with_webmock
107
+
108
+ %w[ get head delete ].each do |verb|
109
+ define_method "http_#{verb}_with_webmock" do
110
+ @webmock_method = verb
111
+ curb_or_webmock do
112
+ send( "http_#{verb}_without_webmock" )
113
+ end
114
+ end
115
+
116
+ alias_method "http_#{verb}_without_webmock", "http_#{verb}"
117
+ alias_method "http_#{verb}", "http_#{verb}_with_webmock"
118
+ end
119
+
120
+ def http_put_with_webmock data
121
+ @webmock_method = :put
122
+ @put_data = data
123
+ curb_or_webmock do
124
+ http_put_without_webmock(data)
125
+ end
126
+ end
127
+ alias_method :http_put_without_webmock, :http_put
128
+ alias_method :http_put, :http_put_with_webmock
129
+
130
+ def http_post_with_webmock data
131
+ @webmock_method = :post
132
+ @post_body = data
133
+ curb_or_webmock do
134
+ http_post_without_webmock(data)
135
+ end
136
+ end
137
+ alias_method :http_post_without_webmock, :http_post
138
+ alias_method :http_post, :http_post_with_webmock
139
+
140
+
141
+ def perform_with_webmock
142
+ @webmock_method ||= :get
143
+ curb_or_webmock do
144
+ perform_without_webmock
145
+ end
146
+ end
147
+ alias :perform_without_webmock :perform
148
+ alias :perform :perform_with_webmock
149
+
150
+ def put_data_with_webmock= data
151
+ @webmock_method = :put
152
+ @put_data = data
153
+ self.put_data_without_webmock = data
154
+ end
155
+ alias_method :put_data_without_webmock=, :put_data=
156
+ alias_method :put_data=, :put_data_with_webmock=
157
+
158
+ def post_body_with_webmock= data
159
+ @webmock_method = :post
160
+ self.post_body_without_webmock = data
161
+ end
162
+ alias_method :post_body_without_webmock=, :post_body=
163
+ alias_method :post_body=, :post_body_with_webmock=
164
+
165
+ def delete_with_webmock= value
166
+ @webmock_method = :delete if value
167
+ self.delete_without_webmock = value
168
+ end
169
+ alias_method :delete_without_webmock=, :delete=
170
+ alias_method :delete=, :delete_with_webmock=
171
+
172
+ def head_with_webmock= value
173
+ @webmock_method = :head if value
174
+ self.head_without_webmock = value
175
+ end
176
+ alias_method :head_without_webmock=, :head=
177
+ alias_method :head=, :head_with_webmock=
178
+
179
+ def body_str_with_webmock
180
+ @body_str || body_str_without_webmock
181
+ end
182
+ alias :body_str_without_webmock :body_str
183
+ alias :body_str :body_str_with_webmock
184
+
185
+ def response_code_with_webmock
186
+ @response_code || response_code_without_webmock
187
+ end
188
+ alias :response_code_without_webmock :response_code
189
+ alias :response_code :response_code_with_webmock
190
+
191
+ def header_str_with_webmock
192
+ @header_str || header_str_without_webmock
193
+ end
194
+ alias :header_str_without_webmock :header_str
195
+ alias :header_str :header_str_with_webmock
196
+
197
+ %w[ success failure header body complete progress ].each do |callback|
198
+ class_eval <<-METHOD, __FILE__, __LINE__
199
+ def on_#{callback}_with_webmock &block
200
+ @on_#{callback} = block
201
+ on_#{callback}_without_webmock &block
202
+ end
203
+ METHOD
204
+ alias_method "on_#{callback}_without_webmock", "on_#{callback}"
205
+ alias_method "on_#{callback}", "on_#{callback}_with_webmock"
206
+ end
207
+
208
+ %w[ http_get http_head http_delete perform ].each do |method|
209
+ class_eval <<-METHOD, __FILE__, __LINE__
210
+ def self.#{method}(url, &block)
211
+ c = new
212
+ c.url = url
213
+ block.call(c) if block
214
+ c.send("#{method}")
215
+ c
216
+ end
217
+ METHOD
218
+ end
219
+
220
+ %w[ put post ].each do |verb|
221
+ class_eval <<-METHOD, __FILE__, __LINE__
222
+ def self.http_#{verb}(url, data, &block)
223
+ c = new
224
+ c.url = url
225
+ block.call(c) if block
226
+ c.send("http_#{verb}", data)
227
+ c
228
+ end
229
+ METHOD
230
+ end
231
+
232
+ module WebmockHelper
233
+ # Borrowed from Patron:
234
+ # http://github.com/toland/patron/blob/master/lib/patron/response.rb
235
+ def self.parse_header_string(header_string)
236
+ status, headers = nil, {}
237
+
238
+ header_string.split(/\r\n/).each do |header|
239
+ if header =~ %r|^HTTP/1.[01] \d\d\d (.*)|
240
+ status = $1
241
+ else
242
+ parts = header.split(':', 2)
243
+ unless parts.empty?
244
+ parts[1].strip! unless parts[1].nil?
245
+ if headers.has_key?(parts[0])
246
+ headers[parts[0]] = [headers[parts[0]]] unless headers[parts[0]].kind_of? Array
247
+ headers[parts[0]] << parts[1]
248
+ else
249
+ headers[parts[0]] = parts[1]
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ return status, headers
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end