webmock 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +113 -0
- data/README.md +84 -18
- data/VERSION +1 -1
- data/lib/webmock.rb +1 -0
- data/lib/webmock/adapters/rspec/webmock_matcher.rb +2 -2
- data/lib/webmock/http_lib_adapters/net_http.rb +11 -13
- data/lib/webmock/request.rb +1 -1
- data/lib/webmock/request_profile.rb +11 -2
- data/lib/webmock/request_signature.rb +8 -2
- data/lib/webmock/request_stub.rb +39 -11
- data/lib/webmock/response.rb +32 -1
- data/lib/webmock/responses_sequence.rb +40 -0
- data/lib/webmock/util/headers.rb +1 -1
- data/lib/webmock/webmock.rb +4 -4
- data/spec/example_curl_output.txt +20 -0
- data/spec/httpclient_spec_helper.rb +4 -0
- data/spec/net_http_spec.rb +8 -0
- data/spec/net_http_spec_helper.rb +10 -1
- data/spec/request_profile_spec.rb +5 -0
- data/spec/request_registry_spec.rb +4 -4
- data/spec/request_signature_spec.rb +35 -0
- data/spec/request_stub_spec.rb +123 -0
- data/spec/response_spec.rb +72 -7
- data/spec/spec_helper.rb +27 -0
- data/spec/webmock_spec.rb +674 -330
- data/test/test_webmock.rb +2 -1
- data/webmock.gemspec +5 -3
- metadata +5 -3
- data/CHANGELOG +0 -36
data/CHANGELOG.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
#Changelog
|
2
|
+
|
3
|
+
## 0.9.0
|
4
|
+
|
5
|
+
* Matching requests against provided block (by Sergio Gil)
|
6
|
+
|
7
|
+
stub_request(:post, "www.example.com").with { |request| request.body == "abc" }.to_return(:body => "def")
|
8
|
+
RestClient.post('www.example.com', 'abc') # ===> "def\n"
|
9
|
+
request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
|
10
|
+
#or
|
11
|
+
assert_requested(:post, "www.example.com") { |req| req.body == "abc" }
|
12
|
+
|
13
|
+
* Matching request body against regular expressions
|
14
|
+
|
15
|
+
stub_request(:post, "www.example.com").with(:body => /^.*world$/).to_return(:body => "abc")
|
16
|
+
RestClient.post('www.example.com', 'hello world') # ===> "abc\n"
|
17
|
+
|
18
|
+
* Matching request headers against regular expressions
|
19
|
+
|
20
|
+
stub_request(:post, "www.example.com").with(:headers => {"Content-Type" => /image\/.+/}).to_return(:body => "abc")
|
21
|
+
RestClient.post('www.example.com', '', {'Content-Type' => 'image/png'}) # ===> "abc\n"
|
22
|
+
|
23
|
+
* Replaying raw responses recorded with `curl -is`
|
24
|
+
|
25
|
+
`curl -is www.example.com > /tmp/example_curl_-is_output.txt`
|
26
|
+
raw_response_file = File.new("/tmp/example_curl_-is_output.txt")
|
27
|
+
|
28
|
+
from file
|
29
|
+
|
30
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file)
|
31
|
+
|
32
|
+
or string
|
33
|
+
|
34
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file.read)
|
35
|
+
|
36
|
+
* Multiple responses for repeated requests
|
37
|
+
|
38
|
+
stub_request(:get, "www.example.com").to_return({:body => "abc"}, {:body => "def"})
|
39
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
40
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
41
|
+
|
42
|
+
* Multiple responses using chained `to_return()` or `to_raise()` declarations
|
43
|
+
|
44
|
+
stub_request(:get, "www.example.com").
|
45
|
+
to_return({:body => "abc"}).then. #then() just is a syntactic sugar
|
46
|
+
to_return({:body => "def"}).then.
|
47
|
+
to_raise(MyException)
|
48
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
49
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
50
|
+
Net::HTTP.get('www.example.com', '/') # ===> MyException raised
|
51
|
+
|
52
|
+
* Specifying number of times given response should be returned
|
53
|
+
|
54
|
+
stub_request(:get, "www.example.com").
|
55
|
+
to_return({:body => "abc"}).times(2).then.
|
56
|
+
to_return({:body => "def"})
|
57
|
+
|
58
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
59
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
60
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
61
|
+
|
62
|
+
* Added support for `Net::HTTP::Post#body_stream`
|
63
|
+
|
64
|
+
This fixes compatibility with new versions of RestClient
|
65
|
+
|
66
|
+
* WebMock doesn't suppress default request headers added by http clients anymore.
|
67
|
+
|
68
|
+
i.e. Net::HTTP adds `'Accept'=>'*/*'` to all requests by default
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
## 0.8.2
|
73
|
+
|
74
|
+
* Fixed issue where WebMock was not closing IO object passed as response body after reading it.
|
75
|
+
* Ruby 1.9.2 compat: Use `File#expand_path` for require path because "." is not be included in LOAD_PATH since Ruby 1.9.2
|
76
|
+
|
77
|
+
|
78
|
+
## 0.8.1
|
79
|
+
|
80
|
+
* Fixed HTTPClient adapter compatibility with Ruby 1.8.6 (reported by Piotr Usewicz)
|
81
|
+
* Net:HTTP adapter now handles request body assigned as Net::HTTP::Post#body attribute (fixed by Mack Earnhardt)
|
82
|
+
* Fixed issue where requests were not matching stubs with Accept header set.(reported by Piotr Usewicz)
|
83
|
+
* Fixed compatibility with Ruby 1.9.1, 1.9.2 and JRuby 1.3.1 (reported by Diego E. “Flameeyes” Pettenò)
|
84
|
+
* Fixed issue with response body declared as IO object and multiple requests (reported by Niels Meersschaert)
|
85
|
+
* Fixed "undefined method `assertion_failure'" error (reported by Nick Plante)
|
86
|
+
|
87
|
+
|
88
|
+
## 0.8.0
|
89
|
+
|
90
|
+
* Support for HTTPClient (sync and async requests)
|
91
|
+
* Support for dynamic responses. Response body and headers can be now declared as lambda.
|
92
|
+
(Thanks to Ivan Vega ( @ivanyv ) for suggesting this feature)
|
93
|
+
* Support for stubbing and expecting requests with empty body
|
94
|
+
* Executing non-stubbed request leads to failed expectation instead of error
|
95
|
+
|
96
|
+
|
97
|
+
### Bug fixes
|
98
|
+
|
99
|
+
* Basic authentication now works correctly
|
100
|
+
* Fixed problem where WebMock didn't call a block with the response when block was provided
|
101
|
+
* Fixed problem where uris with single slash were not matching uris without path provided
|
102
|
+
|
103
|
+
|
104
|
+
## 0.7.3
|
105
|
+
|
106
|
+
* Clarified documentation
|
107
|
+
* Fixed some issues with loading of Webmock classes
|
108
|
+
* Test::Unit and RSpec adapters have to be required separately
|
109
|
+
|
110
|
+
|
111
|
+
## 0.7.2
|
112
|
+
|
113
|
+
* Added support for matching escaped and non escaped URLs
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
WebMock
|
2
2
|
=======
|
3
3
|
|
4
|
-
Library for stubbing
|
4
|
+
Library for stubbing and setting expectations on HTTP requests in Ruby.
|
5
5
|
|
6
6
|
Features
|
7
7
|
--------
|
8
8
|
|
9
|
-
* Stubbing HTTP requests at low
|
9
|
+
* Stubbing HTTP requests at low http client lib level (no need to change tests when you change HTTP library)
|
10
10
|
* Setting and verifying expectations on HTTP requests
|
11
11
|
* Matching requests based on method, URI, headers and body
|
12
12
|
* Smart matching of the same URIs in different representations (also encoded and non encoded forms)
|
@@ -14,7 +14,7 @@ Features
|
|
14
14
|
* Support for Test::Unit and RSpec (and can be easily extended to other frameworks)
|
15
15
|
* Support for Net::HTTP and other http libraries based on Net::HTTP (i.e RightHttpConnection, rest-client, HTTParty)
|
16
16
|
* Support for HTTPClient library (both sync and async requests)
|
17
|
-
* Easy to extend to other HTTP libraries
|
17
|
+
* Easy to extend to other HTTP libraries
|
18
18
|
|
19
19
|
Installation
|
20
20
|
------------
|
@@ -63,10 +63,21 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
63
63
|
http.request(req, "abc")
|
64
64
|
} # ===> Success
|
65
65
|
|
66
|
+
### Matching request body and headers against regular expressions
|
67
|
+
|
68
|
+
stub_request(:post, "www.example.com").
|
69
|
+
with(:body => /^.*world$/, :headers => {"Content-Type" => /image\/.+/}).to_return(:body => "abc")
|
70
|
+
|
71
|
+
uri = URI.parse('http://www.example.com/')
|
72
|
+
req = Net::HTTP::Post.new(uri.path)
|
73
|
+
req['Content-Type'] = 'image/png'
|
74
|
+
res = Net::HTTP.start(uri.host, uri.port) {|http|
|
75
|
+
http.request(req, 'hello world')
|
76
|
+
} # ===> Success
|
77
|
+
|
66
78
|
### Matching custom request headers
|
67
79
|
|
68
|
-
stub_request(:any, "www.example.com").
|
69
|
-
with( :headers=>{ 'Header-Name' => 'Header-Value' } ).to_return(:body => "abc", :status => 200)
|
80
|
+
stub_request(:any, "www.example.com").with(:headers=>{ 'Header-Name' => 'Header-Value' })
|
70
81
|
|
71
82
|
uri = URI.parse('http://www.example.com/')
|
72
83
|
req = Net::HTTP::Post.new(uri.path)
|
@@ -75,6 +86,27 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
75
86
|
http.request(req, 'abc')
|
76
87
|
} # ===> Success
|
77
88
|
|
89
|
+
### Matching requests against provided block
|
90
|
+
|
91
|
+
stub_request(:post, "www.example.com").with { |request| request.body == "abc" }
|
92
|
+
RestClient.post('www.example.com', 'abc') # ===> Success
|
93
|
+
|
94
|
+
### Request with basic authentication
|
95
|
+
|
96
|
+
stub_request(:get, "user:pass@www.example.com")
|
97
|
+
|
98
|
+
Net::HTTP.start('www.example.com') {|http|
|
99
|
+
req = Net::HTTP::Get.new('/')
|
100
|
+
req.basic_auth 'user', 'pass'
|
101
|
+
http.request(req)
|
102
|
+
} # ===> Success
|
103
|
+
|
104
|
+
### Matching uris using regular expressions
|
105
|
+
|
106
|
+
stub_request(:any, /.*example.*/)
|
107
|
+
|
108
|
+
Net::HTTP.get('www.example.com', '/') # ===> Success
|
109
|
+
|
78
110
|
### Stubbing with custom response
|
79
111
|
|
80
112
|
stub_request(:any, "www.example.com").to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 } )
|
@@ -88,6 +120,19 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
88
120
|
stub_request(:any, "www.example.com").to_return(:body => File.new('/tmp/response_body.txt'), :status => 200)
|
89
121
|
|
90
122
|
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
123
|
+
|
124
|
+
### Replaying raw responses recorded with `curl -is`
|
125
|
+
|
126
|
+
`curl -is www.example.com > /tmp/example_curl_-is_output.txt`
|
127
|
+
raw_response_file = File.new("/tmp/example_curl_-is_output.txt")
|
128
|
+
|
129
|
+
from file
|
130
|
+
|
131
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file)
|
132
|
+
|
133
|
+
or string
|
134
|
+
|
135
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file.read)
|
91
136
|
|
92
137
|
### Custom response with dynamically evaluated response
|
93
138
|
|
@@ -96,21 +141,36 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
96
141
|
|
97
142
|
RestClient.post('www.example.net', 'abc') # ===> "abc\n"
|
98
143
|
|
99
|
-
###
|
144
|
+
### Multiple responses for repeated requests
|
100
145
|
|
101
|
-
|
146
|
+
stub_request(:get, "www.example.com").to_return({:body => "abc"}, {:body => "def"})
|
147
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
148
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
149
|
+
|
150
|
+
#after all responses are used the last response will be returned infinitely
|
151
|
+
|
152
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
102
153
|
|
103
|
-
|
104
|
-
req = Net::HTTP::Get.new('/')
|
105
|
-
req.basic_auth 'user', 'pass'
|
106
|
-
http.request(req)
|
107
|
-
} # ===> Success
|
154
|
+
### Multiple responses using chained `to_return()` or `to_raise()` declarations
|
108
155
|
|
109
|
-
|
156
|
+
stub_request(:get, "www.example.com").
|
157
|
+
to_return({:body => "abc"}).then. #then() just is a syntactic sugar
|
158
|
+
to_return({:body => "def"}).then.
|
159
|
+
to_raise(MyException)
|
160
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
161
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
162
|
+
Net::HTTP.get('www.example.com', '/') # ===> MyException raised
|
110
163
|
|
111
|
-
|
164
|
+
### Specifying number of times given response should be returned
|
165
|
+
|
166
|
+
stub_request(:get, "www.example.com").
|
167
|
+
to_return({:body => "abc"}).times(2).then.
|
168
|
+
to_return({:body => "def"})
|
169
|
+
|
170
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
171
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
172
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
112
173
|
|
113
|
-
Net::HTTP.get('www.example.com', '/') # ===> Success
|
114
174
|
|
115
175
|
### Real requests to network can be allowed or disabled
|
116
176
|
|
@@ -146,6 +206,8 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
146
206
|
|
147
207
|
assert_not_requested :get, "http://www.something.com" # ===> Success
|
148
208
|
|
209
|
+
assert_requested(:post, "http://www.example.com", :times => 1) { |req| req.body == "abc" }
|
210
|
+
|
149
211
|
### Expecting real (not stubbed) requests
|
150
212
|
|
151
213
|
WebMock.allow_net_connect!
|
@@ -163,6 +225,8 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
163
225
|
WebMock.should have_requested(:get, "www.example.com").with(:body => "abc", :headers => {'Content-Length' => 3}).twice
|
164
226
|
|
165
227
|
WebMock.should_not have_requested(:get, "www.something.com")
|
228
|
+
|
229
|
+
WebMock.should have_requested(:post, "www.example.com").with { |req| req.body == "abc" }
|
166
230
|
|
167
231
|
### Different way of setting expectations in RSpec
|
168
232
|
|
@@ -172,7 +236,8 @@ You can also use WebMock without RSpec or Test::Unit support:
|
|
172
236
|
|
173
237
|
request(:any, "www.example.com").should_not have_been_made
|
174
238
|
|
175
|
-
|
239
|
+
request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
|
240
|
+
|
176
241
|
## Clearing stubs and request history
|
177
242
|
|
178
243
|
If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
|
@@ -195,7 +260,8 @@ An executed request matches stubbed request if it passes following criteria:
|
|
195
260
|
When request URI matches stubbed request URI string or Regexp pattern<br/>
|
196
261
|
And request method is the same as stubbed request method or stubbed request method is :any<br/>
|
197
262
|
And request body is the same as stubbed request body or stubbed request body is not specified<br/>
|
198
|
-
And request headers match stubbed request headers, or stubbed request headers match a subset of request headers, or stubbed request headers are not specified
|
263
|
+
And request headers match stubbed request headers, or stubbed request headers match a subset of request headers, or stubbed request headers are not specified<br/>
|
264
|
+
And request matches provided block or block is not provided
|
199
265
|
|
200
266
|
## Precedence of stubs
|
201
267
|
|
@@ -299,4 +365,4 @@ I also preferred some things to work differently i.e request stub precedence.
|
|
299
365
|
|
300
366
|
## Copyright
|
301
367
|
|
302
|
-
Copyright 2009 Bartosz Blimke. See LICENSE for details.
|
368
|
+
Copyright 2009-2010 Bartosz Blimke. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.0
|
data/lib/webmock.rb
CHANGED
@@ -69,12 +69,19 @@ module Net #:nodoc: all
|
|
69
69
|
method = request.method.downcase.to_sym
|
70
70
|
|
71
71
|
headers = Hash[*request.to_hash.map {|k,v| [k, v.flatten]}.flatten]
|
72
|
-
|
73
|
-
remove_default_net_http_headers!(headers)
|
74
|
-
|
72
|
+
|
75
73
|
headers.reject! {|k,v| k =~ /[Aa]uthorization/ && v =~ /^Basic / } #we added it to url userinfo
|
76
74
|
|
77
|
-
request.
|
75
|
+
if request.body_stream
|
76
|
+
body = request.body_stream.read
|
77
|
+
request.body_stream = nil
|
78
|
+
end
|
79
|
+
|
80
|
+
if body != nil && body.respond_to?(:read)
|
81
|
+
request.set_body_internal body.read
|
82
|
+
else
|
83
|
+
request.set_body_internal body
|
84
|
+
end
|
78
85
|
|
79
86
|
request_signature = WebMock::RequestSignature.new(method, uri, :body => request.body, :headers => headers)
|
80
87
|
|
@@ -122,15 +129,6 @@ module Net #:nodoc: all
|
|
122
129
|
response
|
123
130
|
end
|
124
131
|
|
125
|
-
def remove_default_net_http_headers!(headers)
|
126
|
-
default_request = Net::HTTPGenericRequest.new('','','','/')
|
127
|
-
default_net_http_headers = Hash[*default_request.to_hash.map {|k,v|
|
128
|
-
[k, v.flatten]
|
129
|
-
}.flatten]
|
130
|
-
headers.reject! {|k,v| default_request[k] == v}
|
131
|
-
headers
|
132
|
-
end
|
133
|
-
|
134
132
|
end
|
135
133
|
|
136
134
|
end
|
data/lib/webmock/request.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
module WebMock
|
2
2
|
|
3
3
|
class RequestProfile < Request
|
4
|
+
|
5
|
+
attr_reader :with_block
|
4
6
|
|
5
|
-
def with(options)
|
7
|
+
def with(options = {}, &block)
|
6
8
|
assign_options(options)
|
9
|
+
@with_block = block
|
7
10
|
self
|
8
11
|
end
|
9
12
|
|
10
13
|
def body=(body)
|
11
14
|
@body = Body.new(body)
|
12
15
|
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
string = super
|
19
|
+
string << " with given block" if @with_block
|
20
|
+
string
|
21
|
+
end
|
13
22
|
|
14
23
|
class Body
|
15
24
|
|
@@ -22,7 +31,7 @@ module WebMock
|
|
22
31
|
def ==(other)
|
23
32
|
other = Body.new(other) unless other.is_a?(Body)
|
24
33
|
other.is_a?(Body) &&
|
25
|
-
(other.is_empty? && self.is_empty? || other.data == self.data)
|
34
|
+
(other.is_empty? && self.is_empty? || other.data == self.data || self.data === other.data )
|
26
35
|
end
|
27
36
|
|
28
37
|
def is_empty?
|
@@ -7,7 +7,8 @@ module WebMock
|
|
7
7
|
match_method(request_profile) &&
|
8
8
|
match_body(request_profile) &&
|
9
9
|
match_headers(request_profile) &&
|
10
|
-
match_uri(request_profile)
|
10
|
+
match_uri(request_profile) &&
|
11
|
+
match_with_block(request_profile)
|
11
12
|
end
|
12
13
|
|
13
14
|
private
|
@@ -26,7 +27,7 @@ module WebMock
|
|
26
27
|
return false if self.headers && !self.headers.empty? && request_profile.headers && request_profile.headers.empty?
|
27
28
|
if request_profile.headers && !request_profile.headers.empty?
|
28
29
|
request_profile.headers.each do | key, value |
|
29
|
-
return false unless (self.headers && self.headers.has_key?(key) && value
|
30
|
+
return false unless (self.headers && self.headers.has_key?(key) && value === self.headers[key])
|
30
31
|
end
|
31
32
|
end
|
32
33
|
return true
|
@@ -39,6 +40,11 @@ module WebMock
|
|
39
40
|
def match_method(request_profile)
|
40
41
|
request_profile.method == self.method || request_profile.method == :any
|
41
42
|
end
|
43
|
+
|
44
|
+
def match_with_block(request_profile)
|
45
|
+
return true unless request_profile.with_block
|
46
|
+
request_profile.with_block.call(self)
|
47
|
+
end
|
42
48
|
end
|
43
49
|
|
44
50
|
|
data/lib/webmock/request_stub.rb
CHANGED
@@ -1,25 +1,53 @@
|
|
1
1
|
module WebMock
|
2
2
|
class RequestStub
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
attr_accessor :request_profile, :responses
|
5
|
+
|
5
6
|
def initialize(method, uri)
|
6
7
|
@request_profile = RequestProfile.new(method, uri)
|
7
|
-
@
|
8
|
+
@responses_sequences = []
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def with(params = {}, &block)
|
13
|
+
@request_profile.with(params, &block)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_return(*response_hashes)
|
18
|
+
@responses_sequences << ResponsesSequence.new([*response_hashes].flatten.map {|r| WebMock::Response.new(r)})
|
8
19
|
self
|
9
20
|
end
|
10
21
|
|
11
|
-
def
|
12
|
-
@
|
22
|
+
def to_raise(*exceptions)
|
23
|
+
@responses_sequences << ResponsesSequence.new([*exceptions].flatten.map {|e| WebMock::Response.new(:exception => e)})
|
13
24
|
self
|
14
25
|
end
|
15
26
|
|
16
|
-
def
|
17
|
-
@
|
27
|
+
def response
|
28
|
+
if @responses_sequences.empty?
|
29
|
+
WebMock::Response.new
|
30
|
+
elsif @responses_sequences.length > 1
|
31
|
+
@responses_sequences.shift if @responses_sequences.first.end?
|
32
|
+
@responses_sequences.first.next_response
|
33
|
+
else
|
34
|
+
@responses_sequences[0].next_response
|
35
|
+
end
|
18
36
|
end
|
19
|
-
|
20
|
-
def
|
21
|
-
|
37
|
+
|
38
|
+
def then
|
39
|
+
self
|
22
40
|
end
|
23
|
-
|
41
|
+
|
42
|
+
def times(number)
|
43
|
+
raise "times(N) accepts integers >= 1 only" if !number.is_a?(Fixnum) || number < 1
|
44
|
+
if @responses_sequences.empty?
|
45
|
+
raise "Invalid WebMock stub declaration." +
|
46
|
+
" times(N) can be declared only after response declaration."
|
47
|
+
end
|
48
|
+
@responses_sequences.last.times_to_repeat += number-1
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
24
52
|
end
|
25
53
|
end
|