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 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)