chrisk-fakeweb 1.1.2.6 → 1.1.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,26 @@
1
1
  fakeweb (development)
2
2
 
3
+ * fix compatibility with Ruby 1.9.1 [Chris Kampmeier]
4
+
5
+ * fix that newlines in file-based responses could be doubled in the response
6
+ object's body [Mark Menard, Chris Kampmeier]
7
+
8
+ * fix unnecessary munging of the transfer-encoding header, which improves
9
+ compatibility with mechanize [Mark Menard]
10
+
11
+ * fix a test and the RCov dependency to be compatible with JRuby [Mark Menard]
12
+
13
+ * remove an unnecessary redefinition of OpenURI::HTTPError [Josh Nichols]
14
+
15
+ * rearrange implementation code into separate files, one per class [Josh Nichols]
16
+
17
+ * fix a bug where FakeWeb.response_for would raise if the request wasn't
18
+ registered [Chris Kampmeier]
19
+
20
+ * add HTTP method support, so FakeWeb takes both the URI and method into
21
+ account for registration, requests, and responses. Backwards-compatible with
22
+ the old method signatures, which didn't have a method param. [Chris Kampmeier]
23
+
3
24
  * start work on Ruby 1.9 compatibility [Chris Kampmeier]
4
25
 
5
26
  * add FakeWeb.allow_net_connect= to enable/disable the pass-through to
File without changes
@@ -3,52 +3,79 @@
3
3
  FakeWeb is a helper for faking web requests in Ruby. It works at a global
4
4
  level, without modifying code or writing extensive stubs.
5
5
 
6
- = Installation
6
+
7
+ == Installation
7
8
 
8
9
  This fork of Blaine Cook's original code has lots of fixes, stability
9
- improvements, and a few new features. To get it, install the latest gem
10
- directly from GitHub (currently 1.1.2.6):
10
+ improvements, and a few new features. It also has new support for Ruby 1.9.1
11
+ and JRuby. To get it, install the latest gem directly from GitHub (currently
12
+ 1.1.2.7):
11
13
 
12
14
  sudo gem install chrisk-fakeweb --source http://gems.github.com
13
15
 
14
- = Examples
16
+
17
+ == Help and discussion
18
+
19
+ There's a brand new mailing list at http://groups.google.com/group/fakeweb-users.
20
+
21
+
22
+ == Development Notes
23
+
24
+ We're currently considering how the API should change to add support for
25
+ request bodies (see Known Issues below). Your input would be really helpful:
26
+ see http://groups.google.com/group/fakeweb-users/browse_thread/thread/44d190a6b12e4273
27
+ for a discussion of some different options. Thanks!
28
+
29
+
30
+ == Examples
15
31
 
16
32
  Start by requiring FakeWeb:
17
33
 
18
34
  require 'rubygems'
19
35
  require 'fake_web'
20
36
 
21
- == Registering basic string responses
37
+ === Registering basic string responses
22
38
 
23
- FakeWeb.register_uri("http://example.com/test1", :string => "Hello World!")
39
+ FakeWeb.register_uri(:get, "http://example.com/test1", :string => "Hello World!")
24
40
 
25
- Net::HTTP.get(URI.parse('http://example.com/test1'))
41
+ Net::HTTP.get(URI.parse("http://example.com/test1"))
26
42
  => "Hello World!"
27
43
 
28
- Net::HTTP.get(URI.parse('http://example.com/test2'))
44
+ Net::HTTP.get(URI.parse("http://example.com/test2"))
29
45
  => FakeWeb is bypassed and the response from a real request is returned
30
46
 
31
- == Replaying a recorded response
47
+ === Replaying a recorded response
32
48
 
33
49
  page = `curl -is http://www.google.com/`
34
- FakeWeb.register_uri('http://www.google.com/', :response => page)
50
+ FakeWeb.register_uri(:get, "http://www.google.com/", :response => page)
35
51
 
36
- Net::HTTP.get(URI.parse('http://www.google.com/'))
52
+ Net::HTTP.get(URI.parse("http://www.google.com/"))
37
53
  # => Full response, including headers
38
54
 
39
- == Adding a custom status to the response
55
+ === Adding a custom status to the response
40
56
 
41
- FakeWeb.register_uri('http://example.com/', :string => "Nothing to be found 'round here",
42
- :status => ["404", "Not Found"])
57
+ FakeWeb.register_uri(:get, "http://example.com/", :string => "Nothing to be found 'round here",
58
+ :status => ["404", "Not Found"])
43
59
 
44
- Net::HTTP.start('example.com') do |req|
45
- response = req.get('/')
60
+ Net::HTTP.start("example.com") do |req|
61
+ response = req.get("/")
46
62
  response.code # => "404"
47
63
  response.message # => "Not Found"
48
64
  response.body # => "Nothing to be found 'round here"
49
65
  end
50
66
 
51
- == Rotating responses
67
+ === Responding to any HTTP method
68
+
69
+ FakeWeb.register_uri(:any, "http://example.com", :string => "response for any HTTP method")
70
+
71
+ If you use the <tt>:any</tt> symbol, the URI you specify will be completely
72
+ stubbed out (regardless of the HTTP method of the request). This can be useful
73
+ for RPC-like services, where the HTTP method isn't significant. (Older
74
+ versions of FakeWeb always behaved like this, and didn't accept the first
75
+ +method+ argument above; this syntax is still supported, for
76
+ backwards-compatibility, but it will probably be deprecated at some point.)
77
+
78
+ === Rotating responses
52
79
 
53
80
  You can optionally call FakeWeb.register_uri with an array of options hashes;
54
81
  these are used, in order, to respond to repeated requests. Once you run out of
@@ -56,17 +83,17 @@ responses, further requests always receive the last response. (You can also send
56
83
  a response more than once before rotating, by specifying a <tt>:times</tt>
57
84
  option for that response.)
58
85
 
59
- FakeWeb.register_uri('http://example.com/posts/1',
86
+ FakeWeb.register_uri(:delete, "http://example.com/posts/1",
60
87
  [{:string => "Post 1 deleted.", :status => ["200", "OK"]},
61
88
  {:string => "Post not found", :status => ["404", "Not Found"]}])
62
89
 
63
- Net::HTTP.start('example.com') do |req|
64
- req.delete('/posts/1').body # => "Post 1 deleted"
65
- req.delete('/posts/1').body # => "Post not found"
66
- req.delete('/posts/1').body # => "Post not found"
90
+ Net::HTTP.start("example.com") do |req|
91
+ req.delete("/posts/1").body # => "Post 1 deleted"
92
+ req.delete("/posts/1").body # => "Post not found"
93
+ req.delete("/posts/1").body # => "Post not found"
67
94
  end
68
95
 
69
- == Clearing registered URIs
96
+ === Clearing registered URIs
70
97
 
71
98
  The FakeWeb registry is a singleton that lasts for the duration of your
72
99
  program, maintaining every fake response you register. If needed, you
@@ -74,25 +101,25 @@ can clean out the registry and remove all registered URIs:
74
101
 
75
102
  FakeWeb.clean_registry
76
103
 
77
- == Blocking all real requests
104
+ === Blocking all real requests
78
105
 
79
106
  When you're using FakeWeb to replace _all_ of your requests, it's useful to
80
107
  catch when requests are made for unregistered URIs (unlike the default
81
108
  behavior, which is to pass those requests through to Net::HTTP as usual).
82
109
 
83
110
  FakeWeb.allow_net_connect = false
84
- Net::HTTP.get(URI.parse('http://example.com/'))
111
+ Net::HTTP.get(URI.parse("http://example.com/"))
85
112
  => raises FakeWeb::NetConnectNotAllowedError
86
113
 
87
114
  FakeWeb.allow_net_connect = true
88
- Net::HTTP.get(URI.parse('http://example.com/'))
115
+ Net::HTTP.get(URI.parse("http://example.com/"))
89
116
  => FakeWeb is bypassed and the response from a real request is returned
90
117
 
91
118
  This is handy when you want to make sure your tests are self-contained, or you
92
119
  want to catch the scenario when a URI is changed in implementation code
93
120
  without a corresponding test change.
94
121
 
95
- = More info
122
+ == More info
96
123
 
97
124
  FakeWeb lets you decouple your test environment from live services without
98
125
  modifying code or writing extensive stubs.
@@ -107,32 +134,32 @@ FakeWeb works with anything based on Net::HTTP--both higher-level wrappers,
107
134
  like OpenURI, as well as a ton of libraries for popular web services.
108
135
 
109
136
 
110
- = Known Issues
111
-
112
- * Requests are only stubbed at the URI level, with no respect to HTTP method.
137
+ == Known Issues
113
138
 
114
- * Similarly, request bodies are ignored, including PUT and POST parameters. If
115
- you need different responses for different request bodies, you need to
116
- request different URLs, and register different responses for each. (Query
117
- strings are fully supported, though.)
139
+ * Request bodies are ignored, including PUT and POST parameters. If you need
140
+ different responses for different request bodies, you need to request
141
+ different URLs, and register different responses for each. (Query strings
142
+ are fully supported, though.)
118
143
 
119
144
 
120
- = Copyright
145
+ == Copyright
121
146
 
122
147
  Copyright 2006-2007 Blaine Cook
123
148
 
124
- Copyright 2008 various contributors
149
+ Copyright 2008-2009 various contributors
150
+
151
+ FakeWeb is free software; you can redistribute it and/or modify it under the
152
+ terms of the GNU General Public License as published by the Free Software
153
+ Foundation; either version 2 of the License, or (at your option) any later
154
+ version.
125
155
 
126
- FakeWeb is free software; you can redistribute it and/or modify
127
- it under the terms of the GNU General Public License as published by
128
- the Free Software Foundation; either version 2 of the License, or
129
- (at your option) any later version.
156
+ FakeWeb is distributed in the hope that it will be useful, but WITHOUT ANY
157
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
158
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
159
+ details.
130
160
 
131
- FakeWeb is distributed in the hope that it will be useful,
132
- but WITHOUT ANY WARRANTY; without even the implied warranty of
133
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134
- GNU General Public License for more details.
161
+ You should have received a copy of the GNU General Public License along
162
+ with FakeWeb; if not, write to the Free Software Foundation, Inc., 51
163
+ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
135
164
 
136
- You should have received a copy of the GNU General Public License
137
- along with FakeWeb; if not, write to the Free Software
138
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
165
+ See <tt>LICENSE.txt</tt> for the full terms.
data/Rakefile CHANGED
@@ -1,24 +1,6 @@
1
- # FakeWeb - Ruby Helper for Faking Web Requests
2
- # Copyright 2006 Blaine Cook <romeda@gmail.com>.
3
- #
4
- # FakeWeb is free software; you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation; either version 2 of the License, or
7
- # (at your option) any later version.
8
- #
9
- # FakeWeb is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with FakeWeb; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
-
18
1
  require 'rubygems'
19
2
  require 'rake/testtask'
20
3
  require 'rake/rdoctask'
21
- require 'rcov/rcovtask'
22
4
 
23
5
  task :default => :test
24
6
 
@@ -32,19 +14,12 @@ desc "Generate Documentation"
32
14
  Rake::RDocTask.new do |rdoc|
33
15
  rdoc.main = "README.rdoc"
34
16
  rdoc.rdoc_dir = "doc"
35
- rdoc.rdoc_files.include("README.rdoc", "COPYING", "CHANGELOG", "lib/*.rb")
17
+ rdoc.rdoc_files.include("README.rdoc", "CHANGELOG", "LICENSE.txt", "lib/*.rb")
36
18
  rdoc.title = "FakeWeb API Documentation"
37
19
  rdoc.options << '--line-numbers' << '--inline-source'
38
20
  rdoc.options << '--charset' << 'utf-8'
39
21
  end
40
22
 
41
- Rcov::RcovTask.new do |t|
42
- t.test_files = FileList['test/**/test*.rb']
43
- t.rcov_opts << "--sort coverage"
44
- t.rcov_opts << "--exclude gems"
45
- t.rcov_opts << "--no-validator-links"
46
- end
47
-
48
23
  desc %{Update ".manifest" with the latest list of project filenames. Respect\
49
24
  .gitignore by excluding everything that git ignores. Update `files` and\
50
25
  `test_files` arrays in "*.gemspec" file if it's present.}
@@ -72,3 +47,17 @@ task :manifest do
72
47
  end
73
48
  File.open('.manifest', 'w') {|f| f << list.join("\n") }
74
49
  end
50
+
51
+ if RUBY_PLATFORM =~ /java/
52
+ puts "rcov support disabled (running under JRuby)."
53
+ elsif RUBY_VERSION =~ /^1\.9/
54
+ puts "rcov support disabled (running under Ruby 1.9)"
55
+ else
56
+ require 'rcov/rcovtask'
57
+ Rcov::RcovTask.new do |t|
58
+ t.test_files = FileList['test/**/test*.rb']
59
+ t.rcov_opts << "--sort coverage"
60
+ t.rcov_opts << "--exclude gems"
61
+ t.rcov_opts << "--no-validator-links"
62
+ end
63
+ end
@@ -1,26 +1,10 @@
1
- # FakeWeb - Ruby Helper for Faking Web Requests
2
- # Copyright 2006 Blaine Cook <romeda@gmail.com>.
3
- #
4
- # FakeWeb is free software; you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation; either version 2 of the License, or
7
- # (at your option) any later version.
8
- #
9
- # FakeWeb is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with FakeWeb; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
-
18
- require 'fake_net_http'
19
1
  require 'singleton'
20
2
 
21
- module OpenURI #:nodoc: all
22
- class HTTPError < StandardError; end;
23
- end
3
+ require 'fake_web/ext/net_http'
4
+ require 'fake_web/registry'
5
+ require 'fake_web/response'
6
+ require 'fake_web/responder'
7
+ require 'fake_web/socket_delegator'
24
8
 
25
9
  module FakeWeb
26
10
 
@@ -61,19 +45,24 @@ module FakeWeb
61
45
  # stubbed.
62
46
  class NetConnectNotAllowedError < StandardError; end;
63
47
 
64
-
65
- # Register +uri+ to be handled according to +options+. +uri+ can be a
66
- # +String+ or an +URI+ object. +options+ must be either a +Hash+ or
67
- # an +Array+ of +Hashes+ (see below) that must contain any one of the
68
- # following keys:
48
+ # call-seq:
49
+ # FakeWeb.register_uri(method, uri, options)
50
+ # FakeWeb.register_uri(uri, options)
51
+ #
52
+ # Register requests using the HTTP method specified by the symbol +method+ for
53
+ # +uri+ to be handled according to +options+. If no +method+ is specified, or
54
+ # you explicitly specify <tt>:any</tt>, the response will be reigstered for
55
+ # any request for +uri+. +uri+ can be a +String+ or a +URI+ object. +options+
56
+ # must be either a +Hash+ or an +Array+ of +Hashes+ (see below) that must
57
+ # contain any one of the following keys:
69
58
  #
70
59
  # <tt>:string</tt>::
71
60
  # Takes a +String+ argument that is returned as the body of the response.
72
- # FakeWeb.register_uri('http://example.com/', :string => "Hello World!")
61
+ # FakeWeb.register_uri(:get, 'http://example.com/', :string => "Hello World!")
73
62
  # <tt>:file</tt>::
74
63
  # Takes a valid filesystem path to a file that is slurped and returned as
75
64
  # the body of the response.
76
- # FakeWeb.register_uri('http://example.com/', :file => "/tmp/my_response_body.txt")
65
+ # FakeWeb.register_uri(:post, 'http://example.com/', :file => "/tmp/my_response_body.txt")
77
66
  # <tt>:response</tt>::
78
67
  # Either an <tt>Net::HTTPResponse</tt>, an +IO+ or a +String+.
79
68
  #
@@ -90,7 +79,7 @@ module FakeWeb
90
79
  #
91
80
  # which can then be used in your test environment like so:
92
81
  #
93
- # FakeWeb.register_uri('http://www.example.com/', :response => 'response_for_www.example.com')
82
+ # FakeWeb.register_uri(:get, 'http://www.example.com/', :response => 'response_for_www.example.com')
94
83
  #
95
84
  # See the <tt>Net::HTTPResponse</tt>
96
85
  # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html]
@@ -116,187 +105,49 @@ module FakeWeb
116
105
  # specified URL is requested. Any +Exception+ class is valid. Example:
117
106
  # FakeWeb.register_uri('http://www.example.com/', :exception => Net::HTTPError)
118
107
  #
119
- def self.register_uri(uri, options)
120
- Registry.instance.register_uri(uri, options)
121
- end
122
-
123
- # Returns the faked Net::HTTPResponse object associated with +uri+.
124
- def self.response_for(uri, &block) #:nodoc: :yields: response
125
- Registry.instance.response_for(uri, &block)
126
- end
127
-
128
- # Checks for presence of +uri+ in the +FakeWeb+ registry.
129
- def self.registered_uri?(uri)
130
- Registry.instance.registered_uri?(uri)
131
- end
132
-
133
- class Registry #:nodoc:
134
- include Singleton
135
-
136
- attr_accessor :uri_map
137
-
138
- def initialize
139
- clean_registry
140
- end
141
-
142
- def clean_registry
143
- self.uri_map = {}
144
- end
145
-
146
- def register_uri(uri, options)
147
- uri_map[normalize_uri(uri)] = [*[options]].flatten.collect { |option|
148
- FakeWeb::Responder.new(uri, option, option[:times])
149
- }
108
+ def self.register_uri(*args)
109
+ method = :any
110
+ case args.length
111
+ when 3 then method, uri, options = *args
112
+ when 2 then uri, options = *args
113
+ else raise ArgumentError.new("wrong number of arguments (#{args.length} for method = :any, uri, options)")
150
114
  end
151
115
 
152
- def registered_uri?(uri)
153
- uri_map.has_key?(normalize_uri(uri))
154
- end
155
-
156
- def registered_uri(uri)
157
- uri = normalize_uri(uri)
158
- return uri_map[uri] if registered_uri?(uri)
159
- end
160
-
161
- def response_for(uri, &block)
162
- responses = registered_uri(uri)
163
-
164
- next_response = responses.last
165
- responses.each { |response|
166
- if response.times and response.times > 0
167
- response.times -= 1
168
- next_response = response
169
- break
170
- end
171
- }
172
-
173
- return next_response.response(&block)
174
- end
175
-
176
- private
177
-
178
- def normalize_uri(uri)
179
- case uri
180
- when URI then uri
181
- else
182
- uri = 'http://' + uri unless uri.match('^https?://')
183
- parsed_uri = URI.parse(uri)
184
- parsed_uri.query = sort_query_params(parsed_uri.query)
185
- parsed_uri
186
- end
187
- end
188
-
189
- def sort_query_params(query)
190
- return nil if query.nil? or query.empty?
191
- query.split('&').sort.join('&')
192
- end
193
- end
194
-
195
- module Response #:nodoc:
196
- def read_body(*args, &block)
197
- yield @body if block_given?
198
- @body
199
- end
116
+ Registry.instance.register_uri(method, uri, options)
200
117
  end
201
118
 
202
- class Responder #:nodoc:
203
-
204
- attr_accessor :uri, :options, :times
205
-
206
- def initialize(uri, options, times)
207
- self.uri = uri
208
- self.options = options
209
- self.times = times ? times : 1
210
- end
211
-
212
- def response(&block)
213
- if has_baked_response?
214
- response = baked_response
215
- else
216
- code, msg = meta_information
217
- response = Net::HTTPResponse.send(:response_class, code.to_s).new(uri, code.to_s, msg)
218
- response.instance_variable_set(:@body, content)
219
- end
220
- response.instance_variable_set(:@read, true)
221
- response.extend FakeWeb::Response
222
-
223
- optionally_raise(response)
224
-
225
- yield response if block_given?
226
-
227
- response
228
- end
229
-
230
- private
231
-
232
- def content
233
- [ :file, :string ].each do |map_option|
234
- next unless options.has_key?(map_option)
235
- return self.send("#{map_option}_response", options[map_option])
236
- end
237
-
238
- return ''
239
- end
240
-
241
- def file_response(path)
242
- IO.readlines(path).join("\n")
243
- end
244
-
245
- def string_response(string)
246
- string
247
- end
248
-
249
- def baked_response
250
- resp = case options[:response]
251
- when Net::HTTPResponse then options[:response]
252
- when String
253
- socket = Net::BufferedIO.new(options[:response])
254
- r = Net::HTTPResponse.read_new(socket)
255
- r.instance_eval { @header['transfer-encoding'] = nil }
256
- r.reading_body(socket, true) {}
257
- r
258
- else raise StandardError, "Handler unimplemented for response #{options[:response]}"
259
- end
260
- end
261
-
262
- def has_baked_response?
263
- options.has_key?(:response)
264
- end
265
-
266
- def optionally_raise(response)
267
- return unless options.has_key?(:exception)
268
- ex_alloc = options[:exception].allocate
269
- ex_instance = case ex_alloc
270
- when Net::HTTPError, OpenURI::HTTPError
271
- options[:exception].new('Exception from FakeWeb', response)
272
- else options[:exception].new
273
- end
274
- raise ex_instance
119
+ # call-seq:
120
+ # FakeWeb.response_for(method, uri)
121
+ # FakeWeb.response_for(uri)
122
+ #
123
+ # Returns the faked Net::HTTPResponse object associated with +uri+.
124
+ def self.response_for(*args, &block) #:nodoc: :yields: response
125
+ method = :any
126
+ case args.length
127
+ when 2 then method, uri = args
128
+ when 1 then uri = args.first
129
+ else raise ArgumentError.new("wrong number of arguments (#{args.length} for method = :any, uri)")
275
130
  end
276
131
 
277
- def meta_information
278
- if options.has_key?(:status); options[:status]
279
- else; [ 200, 'OK' ]
280
- end
281
- end
132
+ Registry.instance.response_for(method, uri, &block)
282
133
  end
283
134
 
284
- class SocketDelegator #:nodoc:
285
-
286
- def initialize(delegate=nil)
287
- @delegate = nil
288
- end
289
-
290
- def method_missing(method, *args, &block)
291
- return @delegate.send(method, *args, &block) if @delegate
292
- return self.send("my_#{method}", *args, &block)
293
- end
294
-
295
- def my_closed?
296
- @closed ||= true
297
- end
298
-
299
- def my_readuntil(*args)
300
- end
135
+ # call-seq:
136
+ # FakeWeb.registered_uri?(method, uri)
137
+ # FakeWeb.registered_uri?(uri)
138
+ #
139
+ # Returns true if +uri+ is registered with FakeWeb. You can optionally
140
+ # specify +method+ to limit the search to a certain HTTP method (or use
141
+ # <tt>:any</tt> to explicitly check against any method).
142
+ def self.registered_uri?(*args)
143
+ method = :any
144
+ case args.length
145
+ when 2 then method, uri = args
146
+ when 1 then uri = args.first
147
+ else raise ArgumentError.new("wrong number of arguments (#{args.length} for method = :any, uri)")
148
+ end
149
+
150
+ Registry.instance.registered_uri?(method, uri)
301
151
  end
302
- end
152
+
153
+ end