chrisk-fakeweb 1.1.2.4 → 1.1.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,48 +1,59 @@
1
1
  fakeweb (development)
2
2
 
3
- [ Chris Kampmeier ]
4
- * add support for Net::HTTP's undocumented full-URI request style (fixes
5
- URI::InvalidURIErrors that you might see in older libraries)
6
- * sort query params before storing internally, so that
7
- http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered
8
- the same URL (although this is technically incorrect, it's much more
9
- convenient--most web apps work that way, and Net::HTTP's use of a hash to
10
- pass query params means that the order in which FakeWeb stores them can be
11
- unpredictable)
12
- * add support for ports in URLs, so that http://example.com/ and
13
- http://example.com:3000/ are not the same
14
- * fix for non-faked SSL requests failing with "Unable to create local socket"
15
- * update Rakefile to fix warning about deprecated code
16
-
17
- -- Chris Kampmeier <chris@kampers.net> Mon, 13 Oct 2008 02:46:12 -0700
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
- [ Blaine Cook ]
22
- * add required dependencies to GemSpec to ensure that tests pass in
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
- [ Blaine Cook ]
30
- * fix for non-existance of :string method on File as presented by open-uri
31
- * fix for curl example test - google redirects to ccTLDs for those outside US
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
- [ Blaine Cook ]
38
- * update code to correspond to ruby 1.8.4
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
- [ Blaine Cook ]
46
- * initial import
47
-
48
- -- Blaine Cook <romeda@gmail.com> Mon, 22 May 2006 11:53:42 -0800
59
+ * initial import [Blaine Cook]
@@ -1,53 +1,73 @@
1
1
  = FakeWeb
2
2
 
3
- A Helper for Faking Web Requests
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
- require 'test/unit'
8
- require 'fake_web'
9
- require 'open-uri'
10
-
11
- class FakeWebExampleTest < Test::Unit::TestCase
12
- def test_request
13
- FakeWeb.register_uri('http://example.com/test_me', :string => "Hello World!")
14
- content = Net::HTTP.get(URI.parse('http://example.com/test_me'))
15
- assert_equal "Hello World!", content
16
- end
17
-
18
- def test_request_with_response
19
- FakeWeb.register_uri('http://www.google.com/', :response => `curl -is http://www.google.com/`)
20
- Net::HTTP.start('www.google.com') do |req|
21
- response = req.get('/')
22
- if response.code == 200
23
- assert_equal "OK", response.message
24
- assert response.body.include?('<title>Google')
25
- elsif response.code == 302
26
- # Google redirects foreign sites to ccTLDs.
27
- assert_equal "Found", response.message
28
- assert response.body.include?('The document has moved')
29
- end
30
- end
31
- end
32
-
33
- def test_request_with_custom_status
34
- FakeWeb.register_uri('http://example.com/', :string => "Nothing to be found 'round here",
35
- :status => ['404', 'Not Found'])
36
- Net::HTTP.start('example.com') do |req|
37
- response = req.get('/')
38
- assert_equal "404", response.code
39
- assert_equal "Not Found", response.message
40
- assert_equal "Nothing to be found 'round here", response.body
41
- end
42
- end
43
-
44
- def test_open_uri
45
- FakeWeb.register_uri('http://example.com/', :string => "Hello, World!")
46
- content = open('http://example.com/').string
47
- assert_equal "Hello, World!", content
48
- end
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
- spec = Gem::Specification.new do |s|
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 :tests do |test|
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
@@ -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
- original_net_http_connect
67
- return original_net_http_request(req, body, &block)
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
 
@@ -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 FakeWeb.clean_registry; FakeWeb::Registry.instance.clean_registry; end
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+ that must contain
33
- # any one of the following keys:
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 FakeWeb.register_uri(uri, options); FakeWeb::Registry.instance.register_uri(uri, options); end
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 FakeWeb.response_for(uri, &block) #:nodoc: :yields: response
80
- FakeWeb::Registry.instance.response_for(uri, &block)
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 FakeWeb.registered_uri?(uri); FakeWeb::Registry.instance.registered_uri?(uri); end
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)] = FakeWeb::Responder.new(uri, options)
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
- return registered_uri(uri).response(&block)
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)