chrisk-fakeweb 1.1.2.4 → 1.1.2.5
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.
- data/CHANGELOG +42 -31
- data/README.rdoc +63 -43
- data/Rakefile +33 -29
- data/lib/fake_net_http.rb +9 -10
- data/lib/fake_web.rb +66 -12
- data/test/test_allow_net_connect.rb +44 -0
- data/test/test_fake_web.rb +35 -35
- data/test/test_fake_web_open_uri.rb +2 -5
- data/test/test_helper.rb +52 -0
- data/test/test_query_string.rb +37 -0
- metadata +17 -6
- data/fakeweb.gemspec +0 -16
- data/setup.rb +0 -1585
- data/test/test_examples.rb +0 -45
data/CHANGELOG
CHANGED
|
@@ -1,48 +1,59 @@
|
|
|
1
1
|
fakeweb (development)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
3
|
+
* improve the test suite to not rely on an internet connection [Chris Kampmeier]
|
|
4
|
+
|
|
5
|
+
* use `rake test` instead of `rake tests` [Josh Nichols]
|
|
6
|
+
|
|
7
|
+
* fix an incompatibility with Ruby 1.8.6 p36 where you'd get "Errno::EINTR:
|
|
8
|
+
Interrupted system call" exceptions in Socket#sysread for any non-faked
|
|
9
|
+
request [Chris Kampmeier]
|
|
10
|
+
|
|
11
|
+
* response rotation: you can now optionally call FakeWeb.register_uri with an
|
|
12
|
+
array of options hashes; these are used, in order, to respond to
|
|
13
|
+
repeated requests (to repeat a response more than once before rotating, use
|
|
14
|
+
the :times option). Once you run out of responses, further requests always
|
|
15
|
+
receive the last response. [Michael Shapiro]
|
|
16
|
+
|
|
17
|
+
* add support for Net::HTTP's undocumented full-URI request style (fixes
|
|
18
|
+
URI::InvalidURIErrors that you might see in older libraries) [Chris Kampmeier]
|
|
19
|
+
|
|
20
|
+
* sort query params before storing internally, so that
|
|
21
|
+
http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered the
|
|
22
|
+
same URL (although this is technically incorrect, it's much more
|
|
23
|
+
convenient--most web apps work that way, and Net::HTTP's use of a hash to pass
|
|
24
|
+
query params means that the order in which FakeWeb stores them can be
|
|
25
|
+
unpredictable) [Chris Kampmeier]
|
|
26
|
+
|
|
27
|
+
* add support for ports in URLs, so that http://example.com/ and
|
|
28
|
+
http://example.com:3000/ are not the same [Chris Kampmeier]
|
|
29
|
+
|
|
30
|
+
* fix for non-faked SSL requests failing with "Unable to create local socket"
|
|
31
|
+
[Chris Kampmeier]
|
|
32
|
+
|
|
33
|
+
* update Rakefile to fix warning about deprecated code [Chris Kampmeier]
|
|
34
|
+
|
|
18
35
|
|
|
19
36
|
fakeweb (1.1.2)
|
|
20
37
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
firebrigade (http://firebrigade.seattlerb.org/)
|
|
38
|
+
* add required dependencies to GemSpec to ensure that tests pass in firebrigade
|
|
39
|
+
(http://firebrigade.seattlerb.org/) [Blaine Cook]
|
|
24
40
|
|
|
25
|
-
-- Blaine Cook <romeda@gmail.com> Wed, 31 Aug 2007 17:26:04 -0800
|
|
26
41
|
|
|
27
42
|
fakeweb (1.1.1)
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
* fix for non-existence of :string method on File as presented by open-uri
|
|
45
|
+
[Blaine Cook]
|
|
46
|
+
|
|
47
|
+
* fix for curl example test - google redirects to ccTLDs for those outside US
|
|
48
|
+
[Blaine Cook]
|
|
32
49
|
|
|
33
|
-
-- Blaine Cook <romeda@gmail.com> Thu, 03 Aug 2006 03:41:48 -0800
|
|
34
50
|
|
|
35
51
|
fakeweb (1.1.0)
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* breaks compatibility with ruby 1.8.2
|
|
53
|
+
* update code to correspond to ruby 1.8.4 (breaks compatibility with ruby 1.8.2)
|
|
54
|
+
[Blaine Cook]
|
|
40
55
|
|
|
41
|
-
-- Blaine Cook <romeda@gmail.com> Tue, 23 May 2006 16:13:26 -0800
|
|
42
56
|
|
|
43
57
|
fakeweb (1.0.0)
|
|
44
58
|
|
|
45
|
-
[
|
|
46
|
-
* initial import
|
|
47
|
-
|
|
48
|
-
-- Blaine Cook <romeda@gmail.com> Mon, 22 May 2006 11:53:42 -0800
|
|
59
|
+
* initial import [Blaine Cook]
|
data/README.rdoc
CHANGED
|
@@ -1,53 +1,73 @@
|
|
|
1
1
|
= FakeWeb
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
FakeWeb is a helper for faking web requests. It works at a global level, without
|
|
4
|
+
modifying code or writing extensive stubs.
|
|
4
5
|
|
|
5
6
|
= Examples
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
8
|
+
== Using a string response
|
|
9
|
+
|
|
10
|
+
FakeWeb.register_uri("http://example.com/test1", :string => "Hello World!")
|
|
11
|
+
|
|
12
|
+
Net::HTTP.get(URI.parse('http://example.com/test1'))
|
|
13
|
+
=> "Hello World!"
|
|
14
|
+
|
|
15
|
+
Net::HTTP.get(URI.parse('http://example.com/test2'))
|
|
16
|
+
=> FakeWeb is bypassed and the response from a real request is returned
|
|
17
|
+
|
|
18
|
+
== Replaying a recorded response
|
|
19
|
+
|
|
20
|
+
page = `curl -is http://www.google.com/`
|
|
21
|
+
FakeWeb.register_uri('http://www.google.com/', :response => page)
|
|
22
|
+
|
|
23
|
+
Net::HTTP.get(URI.parse('http://www.google.com/'))
|
|
24
|
+
# => Full response, including headers
|
|
25
|
+
|
|
26
|
+
== Adding a custom status to the response
|
|
27
|
+
|
|
28
|
+
FakeWeb.register_uri('http://example.com/', :string => "Nothing to be found 'round here",
|
|
29
|
+
:status => ["404", "Not Found"])
|
|
30
|
+
|
|
31
|
+
Net::HTTP.start('example.com') do |req|
|
|
32
|
+
response = req.get('/')
|
|
33
|
+
response.code # => "404"
|
|
34
|
+
response.message # => "Not Found"
|
|
35
|
+
response.body # => "Nothing to be found 'round here"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
== Rotating responses
|
|
39
|
+
|
|
40
|
+
You can optionally call FakeWeb.register_uri with an array of options hashes;
|
|
41
|
+
these are used, in order, to respond to repeated requests. Once you run out of
|
|
42
|
+
responses, further requests always receive the last response. (You can also send
|
|
43
|
+
a response more than once before rotating, by specifying a <tt>:times</tt>
|
|
44
|
+
option for that response.)
|
|
45
|
+
|
|
46
|
+
FakeWeb.register_uri('http://example.com/posts/1',
|
|
47
|
+
[{:string => "Post 1 deleted.", :status => ["200", "OK"]},
|
|
48
|
+
{:string => "Post not found", :status => ["404", "Not Found"]}])
|
|
49
|
+
|
|
50
|
+
Net::HTTP.start('example.com') do |req|
|
|
51
|
+
req.delete('/posts/1').body # => "Post 1 deleted"
|
|
52
|
+
req.delete('/posts/1').body # => "Post not found"
|
|
53
|
+
req.delete('/posts/1').body # => "Post not found"
|
|
49
54
|
end
|
|
50
55
|
|
|
56
|
+
== Requesting with OpenURI
|
|
57
|
+
|
|
58
|
+
FakeWeb.register_uri('http://example.com/', :string => "Hello, World!")
|
|
59
|
+
|
|
60
|
+
open('http://example.com/').string
|
|
61
|
+
=> "Hello, World!"
|
|
62
|
+
|
|
63
|
+
== Clearing registered URIs
|
|
64
|
+
|
|
65
|
+
The FakeWeb registry is a singleton that lasts for the duration of your
|
|
66
|
+
program, maintaining every fake responses you register. If needed, you
|
|
67
|
+
can clean out the registry and remove all registered URIs:
|
|
68
|
+
|
|
69
|
+
FakeWeb.clean_registry
|
|
70
|
+
|
|
51
71
|
|
|
52
72
|
= Description
|
|
53
73
|
|
data/Rakefile
CHANGED
|
@@ -16,40 +16,14 @@
|
|
|
16
16
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
require 'rubygems'
|
|
19
|
-
require 'rake/gempackagetask'
|
|
20
19
|
require 'rake/testtask'
|
|
21
20
|
require 'rake/rdoctask'
|
|
22
21
|
require 'rcov/rcovtask'
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
s.add_dependency('rake')
|
|
26
|
-
s.add_dependency('rcov')
|
|
27
|
-
s.name = "FakeWeb"
|
|
28
|
-
s.version = "1.1.2.4"
|
|
29
|
-
s.author = "Blaine Cook"
|
|
30
|
-
s.email = "romeda@gmail.com"
|
|
31
|
-
s.homepage = "http://fakeweb.rubyforge.org/"
|
|
32
|
-
s.platform = Gem::Platform::RUBY
|
|
33
|
-
s.summary = "A test helper that makes it simple to test HTTP interaction"
|
|
34
|
-
s.files = FileList["{test,lib}/**/*", '[A-Z]*'].exclude("rdoc", ".svn").to_a
|
|
35
|
-
s.require_path = "lib"
|
|
36
|
-
s.test_files = Dir.glob("test/test_*.rb")
|
|
37
|
-
s.has_rdoc = true
|
|
38
|
-
s.extra_rdoc_files = ["README.rdoc", "COPYING"]
|
|
39
|
-
s.rubyforge_project = "fakeweb"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
|
43
|
-
pkg.gem_spec = spec
|
|
44
|
-
pkg.need_tar = true
|
|
45
|
-
pkg.need_zip = true
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
desc "Default Task"
|
|
49
|
-
task :default => [:tests]
|
|
23
|
+
task :default => :test
|
|
50
24
|
|
|
51
25
|
desc "Run All Tests"
|
|
52
|
-
Rake::TestTask.new :
|
|
26
|
+
Rake::TestTask.new :test do |test|
|
|
53
27
|
test.test_files = ["test/**/*.rb"]
|
|
54
28
|
test.verbose = true
|
|
55
29
|
end
|
|
@@ -58,11 +32,41 @@ desc "Generate Documentation"
|
|
|
58
32
|
Rake::RDocTask.new do |rdoc|
|
|
59
33
|
rdoc.main = "README.rdoc"
|
|
60
34
|
rdoc.rdoc_dir = "doc"
|
|
61
|
-
rdoc.rdoc_files.include("README.rdoc", "COPYING", "lib/*.rb")
|
|
35
|
+
rdoc.rdoc_files.include("README.rdoc", "COPYING", "CHANGELOG", "lib/*.rb")
|
|
62
36
|
rdoc.title = "FakeWeb"
|
|
63
37
|
end
|
|
64
38
|
|
|
65
39
|
Rcov::RcovTask.new do |t|
|
|
66
40
|
t.test_files = FileList['test/**/test*.rb']
|
|
67
41
|
t.rcov_opts << "--sort coverage"
|
|
42
|
+
t.rcov_opts << "--exclude gems"
|
|
43
|
+
t.rcov_opts << "--no-validator-links"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc %{Update ".manifest" with the latest list of project filenames. Respect\
|
|
47
|
+
.gitignore by excluding everything that git ignores. Update `files` and\
|
|
48
|
+
`test_files` arrays in "*.gemspec" file if it's present.}
|
|
49
|
+
task :manifest do
|
|
50
|
+
list = Dir['**/*'].sort
|
|
51
|
+
spec_file = Dir['*.gemspec'].first
|
|
52
|
+
list -= [spec_file] if spec_file
|
|
53
|
+
|
|
54
|
+
File.read('.gitignore').each_line do |glob|
|
|
55
|
+
glob = glob.chomp.sub(/^\//, '')
|
|
56
|
+
list -= Dir[glob]
|
|
57
|
+
list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
|
|
58
|
+
puts "excluding #{glob}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if spec_file
|
|
62
|
+
spec = File.read spec_file
|
|
63
|
+
spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
|
|
64
|
+
assignment = $1
|
|
65
|
+
bunch = $2 ? list.grep(/^test\//) : list
|
|
66
|
+
'%s%%w(%s)' % [assignment, bunch.join(' ')]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
File.open(spec_file, 'w') {|f| f << spec }
|
|
70
|
+
end
|
|
71
|
+
File.open('.manifest', 'w') {|f| f << list.join("\n") }
|
|
68
72
|
end
|
data/lib/fake_net_http.rb
CHANGED
|
@@ -23,6 +23,8 @@ module Net #:nodoc:
|
|
|
23
23
|
|
|
24
24
|
class BufferedIO #:nodoc:
|
|
25
25
|
def initialize( io, debug_output = nil )
|
|
26
|
+
@read_timeout = 60
|
|
27
|
+
@rbuf = ''
|
|
26
28
|
@debug_output = debug_output
|
|
27
29
|
@io = case io
|
|
28
30
|
when Socket, OpenSSL::SSL::SSLSocket, IO: io
|
|
@@ -30,16 +32,8 @@ module Net #:nodoc:
|
|
|
30
32
|
File.exists?(io) ? File.open(io, "r") : StringIO.new(io)
|
|
31
33
|
end
|
|
32
34
|
raise "Unable to create local socket" unless @io
|
|
33
|
-
connect
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
def connect(*args)
|
|
37
|
-
@rbuf = ''
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def rbuf_fill
|
|
41
|
-
@rbuf << @io.sysread(1024)
|
|
42
|
-
end
|
|
43
37
|
end
|
|
44
38
|
|
|
45
39
|
class HTTP #:nodoc:
|
|
@@ -63,8 +57,13 @@ module Net #:nodoc:
|
|
|
63
57
|
@socket = Net::HTTP.socket_type.new
|
|
64
58
|
return FakeWeb.response_for(uri, &block)
|
|
65
59
|
else
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
if FakeWeb.allow_net_connect?
|
|
61
|
+
original_net_http_connect
|
|
62
|
+
return original_net_http_request(req, body, &block)
|
|
63
|
+
else
|
|
64
|
+
expected = FakeWeb::Registry.instance.uri_map.keys
|
|
65
|
+
raise "unexpected HTTP #{req.method} to #{uri}\n-- expected one of #{expected.inspect}"
|
|
66
|
+
end
|
|
68
67
|
end
|
|
69
68
|
end
|
|
70
69
|
|
data/lib/fake_web.rb
CHANGED
|
@@ -26,11 +26,39 @@ module FakeWeb
|
|
|
26
26
|
|
|
27
27
|
# Resets the FakeWeb Registry. This will force all subsequent web requests to
|
|
28
28
|
# behave as real requests.
|
|
29
|
-
def
|
|
29
|
+
def self.clean_registry
|
|
30
|
+
Registry.instance.clean_registry
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Enables or disables real HTTP connections for requests that don't match
|
|
34
|
+
# registered URIs.
|
|
35
|
+
#
|
|
36
|
+
# If you set <tt>FakeWeb.allow_net_connect = false</tt> and subsequently try
|
|
37
|
+
# to make a request to a URI you haven't registered with #register_uri, an
|
|
38
|
+
# exception will be raised. This is handy when you want to make sure your
|
|
39
|
+
# tests are self-contained, or want to catch the scenario when a URI is
|
|
40
|
+
# changed in implementation code without a corresponding test change.
|
|
41
|
+
#
|
|
42
|
+
# When <tt>FakeWeb.allow_net_connect = true</tt> (the default), requests to
|
|
43
|
+
# URIs not registered with FakeWeb are passed through to Net::HTTP.
|
|
44
|
+
def self.allow_net_connect=(allowed)
|
|
45
|
+
@allow_net_connect = allowed
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Enable pass-through to Net::HTTP by default.
|
|
49
|
+
self.allow_net_connect = true
|
|
50
|
+
|
|
51
|
+
# Returns +true+ if requests to URIs not registered with FakeWeb are passed
|
|
52
|
+
# through to Net::HTTP for normal processing (the default). Returns +false+
|
|
53
|
+
# if an exception is raised for these requests.
|
|
54
|
+
def self.allow_net_connect?
|
|
55
|
+
@allow_net_connect
|
|
56
|
+
end
|
|
30
57
|
|
|
31
58
|
# Register +uri+ to be handled according to +options+. +uri+ can be a
|
|
32
|
-
# +String+ or an +URI+ object. +options+ must be a +Hash+
|
|
33
|
-
# any one of the
|
|
59
|
+
# +String+ or an +URI+ object. +options+ must be either a +Hash+ or
|
|
60
|
+
# an +Array+ of +Hashes+ (see below) that must contain any one of the
|
|
61
|
+
# following keys:
|
|
34
62
|
#
|
|
35
63
|
# <tt>:string</tt>::
|
|
36
64
|
# Takes a +String+ argument that is returned as the body of the response.
|
|
@@ -61,6 +89,14 @@ module FakeWeb
|
|
|
61
89
|
# documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html]
|
|
62
90
|
# for more information on creating custom response objects.
|
|
63
91
|
#
|
|
92
|
+
# +options+ may also be an +Array+ containing a list of the above-described +Hash+.
|
|
93
|
+
# In this case, FakeWeb will rotate through each provided response, you may optionally
|
|
94
|
+
# provide:
|
|
95
|
+
#
|
|
96
|
+
# <tt>:times</tt>::
|
|
97
|
+
# The number of times this response will be used. Decremented by one each time it's called.
|
|
98
|
+
# FakeWeb will use the final provided request indefinitely, regardless of its :times parameter.
|
|
99
|
+
#
|
|
64
100
|
# Two optional arguments are also accepted:
|
|
65
101
|
#
|
|
66
102
|
# <tt>:status</tt>::
|
|
@@ -73,15 +109,19 @@ module FakeWeb
|
|
|
73
109
|
# specified URL is requested. Any +Exception+ class is valid. Example:
|
|
74
110
|
# FakeWeb.register_uri('http://www.example.com/', :exception => Net::HTTPError)
|
|
75
111
|
#
|
|
76
|
-
def
|
|
112
|
+
def self.register_uri(uri, options)
|
|
113
|
+
Registry.instance.register_uri(uri, options)
|
|
114
|
+
end
|
|
77
115
|
|
|
78
116
|
# Returns the faked Net::HTTPResponse object associated with +uri+.
|
|
79
|
-
def
|
|
80
|
-
|
|
117
|
+
def self.response_for(uri, &block) #:nodoc: :yields: response
|
|
118
|
+
Registry.instance.response_for(uri, &block)
|
|
81
119
|
end
|
|
82
120
|
|
|
83
121
|
# Checks for presence of +uri+ in the +FakeWeb+ registry.
|
|
84
|
-
def
|
|
122
|
+
def self.registered_uri?(uri)
|
|
123
|
+
Registry.instance.registered_uri?(uri)
|
|
124
|
+
end
|
|
85
125
|
|
|
86
126
|
class Registry #:nodoc:
|
|
87
127
|
include Singleton
|
|
@@ -97,7 +137,9 @@ module FakeWeb
|
|
|
97
137
|
end
|
|
98
138
|
|
|
99
139
|
def register_uri(uri, options)
|
|
100
|
-
uri_map[normalize_uri(uri)] =
|
|
140
|
+
uri_map[normalize_uri(uri)] = [*[options]].flatten.collect { |option|
|
|
141
|
+
FakeWeb::Responder.new(uri, option, option[:times])
|
|
142
|
+
}
|
|
101
143
|
end
|
|
102
144
|
|
|
103
145
|
def registered_uri?(uri)
|
|
@@ -110,7 +152,18 @@ module FakeWeb
|
|
|
110
152
|
end
|
|
111
153
|
|
|
112
154
|
def response_for(uri, &block)
|
|
113
|
-
|
|
155
|
+
responses = registered_uri(uri)
|
|
156
|
+
|
|
157
|
+
next_response = responses.last
|
|
158
|
+
responses.each { |response|
|
|
159
|
+
if response.times and response.times > 0
|
|
160
|
+
response.times -= 1
|
|
161
|
+
next_response = response
|
|
162
|
+
break
|
|
163
|
+
end
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return next_response.response(&block)
|
|
114
167
|
end
|
|
115
168
|
|
|
116
169
|
private
|
|
@@ -127,7 +180,7 @@ module FakeWeb
|
|
|
127
180
|
end
|
|
128
181
|
|
|
129
182
|
def sort_query_params(query)
|
|
130
|
-
return nil if query.nil?
|
|
183
|
+
return nil if query.nil? or query.empty?
|
|
131
184
|
query.split('&').sort.join('&')
|
|
132
185
|
end
|
|
133
186
|
end
|
|
@@ -141,11 +194,12 @@ module FakeWeb
|
|
|
141
194
|
|
|
142
195
|
class Responder #:nodoc:
|
|
143
196
|
|
|
144
|
-
attr_accessor :uri, :options
|
|
197
|
+
attr_accessor :uri, :options, :times
|
|
145
198
|
|
|
146
|
-
def initialize(uri, options)
|
|
199
|
+
def initialize(uri, options, times)
|
|
147
200
|
self.uri = uri
|
|
148
201
|
self.options = options
|
|
202
|
+
self.times = times ? times : 1
|
|
149
203
|
end
|
|
150
204
|
|
|
151
205
|
def response(&block)
|