Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow requests to be ignored by defining a block.

This is much more flexible than the other config options for ignoring
requests.

Closes #90.
commit 531896caaf094a298baf8a62e490eeda0d31ee15 1 parent 69131bf
Myron Marston authored
61 features/configuration/ignore_hosts.feature
View
@@ -1,61 +0,0 @@
-Feature: ignore_hosts
-
- The `ignore_hosts` configuration option can be used to prevent VCR
- from having any affect on requests to particular hosts.
- Requests to ignored hosts will not be recorded and will always be
- allowed, regardless of the record mode, and even outside of a
- `VCR.use_cassette` block.
-
- If you only want to ignore localhost (and its various aliases) you
- may want to use the `ignore_localhost` option instead.
-
- Background:
- Given a file named "sinatra_app.rb" with:
- """ruby
- response_count = 0
- start_sinatra_app(:port => 7777) do
- get('/') { "Response #{response_count += 1}" }
- end
- """
-
- Scenario Outline: ignored host requests are not recorded and are always allowed
- Given a file named "ignore_hosts.rb" with:
- """ruby
- include_http_adapter_for("<http_lib>")
- require 'sinatra_app.rb'
-
- require 'vcr'
-
- VCR.configure do |c|
- c.ignore_hosts '127.0.0.1', 'localhost'
- c.cassette_library_dir = 'cassettes'
- <configuration>
- end
-
- VCR.use_cassette('example') do
- puts response_body_for(:get, "http://localhost:7777/")
- end
-
- puts response_body_for(:get, "http://localhost:7777/")
- """
- When I run `ruby ignore_hosts.rb`
- Then it should pass with:
- """
- Response 1
- Response 2
- """
- And the file "cassettes/example.yml" should not exist
-
- Examples:
- | configuration | http_lib |
- | c.hook_into :fakeweb | net/http |
- | c.hook_into :webmock | net/http |
- | c.hook_into :webmock | httpclient |
- | c.hook_into :webmock | curb |
- | c.hook_into :webmock | patron |
- | c.hook_into :webmock | em-http-request |
- | c.hook_into :webmock | typhoeus |
- | c.hook_into :typhoeus | typhoeus |
- | c.hook_into :excon | excon |
- | | faraday (w/ net_http) |
-
97 features/configuration/ignore_localhost.feature
View
@@ -1,97 +0,0 @@
-Feature: ignore_localhost
-
- The `ignore_localhost` configuration option can be used to prevent VCR
- from having any affect on localhost requests. If set to true, it will
- never record them and always allow them, regardless of the record mode,
- and even outside of a `VCR.use_cassette` block.
-
- This is particularly useful when you use VCR with Capybara, since
- Capybara starts a localhost server and pings it when you use one of
- its javascript drivers.
-
- Background:
- Given a file named "sinatra_app.rb" with:
- """ruby
- response_count = 0
- start_sinatra_app(:port => 7777) do
- get('/') { "Response #{response_count += 1}" }
- end
- """
-
- Scenario Outline: localhost requests are not treated differently by default
- Given a file named "localhost_not_ignored.rb" with:
- """ruby
- include_http_adapter_for("<http_lib>")
- require 'sinatra_app.rb'
-
- require 'vcr'
-
- VCR.configure do |c|
- c.cassette_library_dir = 'cassettes'
- <configuration>
- end
-
- VCR.use_cassette('localhost') do
- response_body_for(:get, "http://localhost:7777/")
- end
-
- response_body_for(:get, "http://localhost:7777/")
- """
- When I run `ruby localhost_not_ignored.rb`
- Then it should fail with "Real HTTP connections are disabled"
- And the file "cassettes/localhost.yml" should contain "body: Response 1"
-
- Examples:
- | configuration | http_lib |
- | c.hook_into :fakeweb | net/http |
- | c.hook_into :webmock | net/http |
- | c.hook_into :webmock | httpclient |
- | c.hook_into :webmock | curb |
- | c.hook_into :webmock | patron |
- | c.hook_into :webmock | em-http-request |
- | c.hook_into :webmock | typhoeus |
- | c.hook_into :typhoeus | typhoeus |
- | c.hook_into :excon | excon |
- | c.hook_into :faraday | faraday (w/ net_http) |
-
- Scenario Outline: localhost requests are allowed and not recorded when ignore_localhost = true
- Given a file named "ignore_localhost_true.rb" with:
- """ruby
- include_http_adapter_for("<http_lib>")
- require 'sinatra_app.rb'
-
- require 'vcr'
-
- VCR.configure do |c|
- c.ignore_localhost = true
- c.cassette_library_dir = 'cassettes'
- <configuration>
- end
-
- VCR.use_cassette('localhost') do
- puts response_body_for(:get, "http://localhost:7777/")
- end
-
- puts response_body_for(:get, "http://localhost:7777/")
- """
- When I run `ruby ignore_localhost_true.rb`
- Then it should pass with:
- """
- Response 1
- Response 2
- """
- And the file "cassettes/localhost.yml" should not exist
-
- Examples:
- | configuration | http_lib |
- | c.hook_into :fakeweb | net/http |
- | c.hook_into :webmock | net/http |
- | c.hook_into :webmock | httpclient |
- | c.hook_into :webmock | curb |
- | c.hook_into :webmock | patron |
- | c.hook_into :webmock | em-http-request |
- | c.hook_into :webmock | typhoeus |
- | c.hook_into :typhoeus | typhoeus |
- | c.hook_into :excon | excon |
- | c.hook_into :faraday | faraday (w/ net_http) |
-
186 features/configuration/ignore_request.feature
View
@@ -0,0 +1,186 @@
+Feature: Ignore Request
+
+ By default, VCR hooks into every request, either allowing it and recording
+ it, or playing back a recorded response, or raising an error to force you
+ to deal with the new request. In some situations, you may prefer to have
+ VCR ignore some requests.
+
+ VCR provides 3 configuration options to accomplish this:
+
+ * `ignore_request { |req| ... }` will ignore any request for which the
+ given block returns true.
+ * `ignore_hosts 'foo.com', 'bar.com'` allows you to specify particular
+ hosts to ignore.
+ * `ignore_localhost = true` is equivalent to `ignore_hosts 'localhost',
+ '127.0.0.1', '0.0.0.0'`. It is particularly useful for when you use
+ VCR with a javascript-enabled capybara driver, since capybara boots
+ your rack app and makes localhost requests to it to check that it has
+ booted.
+
+ Ignored requests are not recorded and are always allowed, regardless of
+ the record mode, and even outside of a `VCR.use_cassette` block.
+
+ Background:
+ Given a file named "sinatra_app.rb" with:
+ """ruby
+ response_count = 0
+ start_sinatra_app(:port => 7777) do
+ get('/') { "Port 7777 Response #{response_count += 1}" }
+ end
+ """
+
+ Scenario Outline: ignore requests to a specific port
+ Given a file named "ignore_request.rb" with:
+ """ruby
+ include_http_adapter_for("<http_lib>")
+ require 'sinatra_app.rb'
+
+ response_count = 0
+ start_sinatra_app(:port => 8888) do
+ get('/') { "Port 8888 Response #{response_count += 1}" }
+ end
+
+ require 'vcr'
+
+ VCR.configure do |c|
+ c.ignore_request do |request|
+ URI(request.uri).port == 7777
+ end
+
+ c.cassette_library_dir = 'cassettes'
+ <configuration>
+ end
+
+ VCR.use_cassette('example') do
+ puts response_body_for(:get, "http://localhost:8888/")
+ end
+
+ VCR.use_cassette('example') do
+ puts response_body_for(:get, "http://localhost:7777/")
+ end
+
+ puts response_body_for(:get, "http://localhost:7777/")
+ puts response_body_for(:get, "http://localhost:8888/")
+ """
+ When I run `ruby ignore_request.rb`
+ Then it should fail with "Real HTTP connections are disabled. Request: GET http://localhost:8888/"
+ And the output should contain:
+ """
+ Port 8888 Response 1
+ Port 7777 Response 1
+ Port 7777 Response 2
+ """
+ And the file "cassettes/example.yml" should contain "body: Port 8888"
+ And the file "cassettes/example.yml" should not contain "body: Port 7777"
+
+ Examples:
+ | configuration | http_lib |
+ | c.hook_into :fakeweb | net/http |
+ | c.hook_into :webmock | net/http |
+ | c.hook_into :typhoeus | typhoeus |
+ | c.hook_into :excon | excon |
+ | c.hook_into :faraday | faraday (w/ net_http) |
+
+ Scenario Outline: ignored host requests are not recorded and are always allowed
+ Given a file named "ignore_hosts.rb" with:
+ """ruby
+ include_http_adapter_for("<http_lib>")
+ require 'sinatra_app.rb'
+
+ require 'vcr'
+
+ VCR.configure do |c|
+ c.ignore_hosts '127.0.0.1', 'localhost'
+ c.cassette_library_dir = 'cassettes'
+ <configuration>
+ end
+
+ VCR.use_cassette('example') do
+ puts response_body_for(:get, "http://localhost:7777/")
+ end
+
+ puts response_body_for(:get, "http://localhost:7777/")
+ """
+ When I run `ruby ignore_hosts.rb`
+ Then it should pass with:
+ """
+ Port 7777 Response 1
+ Port 7777 Response 2
+ """
+ And the file "cassettes/example.yml" should not exist
+
+ Examples:
+ | configuration | http_lib |
+ | c.hook_into :fakeweb | net/http |
+ | c.hook_into :webmock | net/http |
+ | c.hook_into :typhoeus | typhoeus |
+ | c.hook_into :excon | excon |
+ | c.hook_into :faraday | faraday (w/ net_http) |
+
+ Scenario Outline: localhost requests are not treated differently by default
+ Given a file named "localhost_not_ignored.rb" with:
+ """ruby
+ include_http_adapter_for("<http_lib>")
+ require 'sinatra_app.rb'
+
+ require 'vcr'
+
+ VCR.configure do |c|
+ c.cassette_library_dir = 'cassettes'
+ <configuration>
+ end
+
+ VCR.use_cassette('localhost') do
+ response_body_for(:get, "http://localhost:7777/")
+ end
+
+ response_body_for(:get, "http://localhost:7777/")
+ """
+ When I run `ruby localhost_not_ignored.rb`
+ Then it should fail with "Real HTTP connections are disabled"
+ And the file "cassettes/localhost.yml" should contain "body: Port 7777 Response 1"
+
+ Examples:
+ | configuration | http_lib |
+ | c.hook_into :fakeweb | net/http |
+ | c.hook_into :webmock | net/http |
+ | c.hook_into :typhoeus | typhoeus |
+ | c.hook_into :excon | excon |
+ | c.hook_into :faraday | faraday (w/ net_http) |
+
+ Scenario Outline: localhost requests are allowed and not recorded when ignore_localhost = true
+ Given a file named "ignore_localhost_true.rb" with:
+ """ruby
+ include_http_adapter_for("<http_lib>")
+ require 'sinatra_app.rb'
+
+ require 'vcr'
+
+ VCR.configure do |c|
+ c.ignore_localhost = true
+ c.cassette_library_dir = 'cassettes'
+ <configuration>
+ end
+
+ VCR.use_cassette('localhost') do
+ puts response_body_for(:get, "http://localhost:7777/")
+ end
+
+ puts response_body_for(:get, "http://localhost:7777/")
+ """
+ When I run `ruby ignore_localhost_true.rb`
+ Then it should pass with:
+ """
+ Port 7777 Response 1
+ Port 7777 Response 2
+ """
+ And the file "cassettes/localhost.yml" should not exist
+
+ Examples:
+ | configuration | http_lib |
+ | c.hook_into :fakeweb | net/http |
+ | c.hook_into :webmock | net/http |
+ | c.hook_into :typhoeus | typhoeus |
+ | c.hook_into :excon | excon |
+ | c.hook_into :faraday | faraday (w/ net_http) |
+
4 lib/vcr/configuration.rb
View
@@ -48,6 +48,10 @@ def ignore_localhost=(value)
VCR.request_ignorer.ignore_localhost = value
end
+ def ignore_request(&block)
+ VCR.request_ignorer.ignore_request(&block)
+ end
+
attr_writer :allow_http_connections_when_no_cassette
def allow_http_connections_when_no_cassette?
!!@allow_http_connections_when_no_cassette
14 lib/vcr/request_ignorer.rb
View
@@ -1,10 +1,21 @@
require 'uri'
require 'set'
+require 'vcr/util/hooks'
module VCR
class RequestIgnorer
+ include VCR::Hooks
+
+ define_hook :ignore_request
+
LOCALHOST_ALIASES = %w( localhost 127.0.0.1 0.0.0.0 )
+ def initialize
+ ignore_request do |request|
+ ignored_hosts.include?(URI(request.uri).host)
+ end
+ end
+
def ignore_localhost=(value)
if value
ignore_hosts(*LOCALHOST_ALIASES)
@@ -18,7 +29,8 @@ def ignore_hosts(*hosts)
end
def ignore?(request)
- ignored_hosts.include?(URI(request.uri).host)
+ tag = nil # we don't use tags here...
+ invoke_hook(:ignore_request, tag, request).any?
end
private
4 lib/vcr/util/hooks.rb
View
@@ -1,3 +1,5 @@
+require 'vcr/util/variable_args_block_caller'
+
module VCR
module Hooks
include VariableArgsBlockCaller
@@ -7,7 +9,7 @@ def self.included(klass)
end
def invoke_hook(hook, tag=nil, *args)
- hooks_for(hook, tag).each do |callback|
+ hooks_for(hook, tag).map do |callback|
call_block(callback, *args)
end
end
9 spec/vcr/configuration_spec.rb
View
@@ -92,6 +92,15 @@
end
end
+ describe '#ignore_request' do
+ it 'registers the given block with the request ignorer' do
+ block_called = false
+ subject.ignore_request { |r| block_called = true }
+ VCR.request_ignorer.ignore?(stub(:uri => 'http://foo.com/'))
+ block_called.should be_true
+ end
+ end
+
describe '#allow_http_connections_when_no_cassette=' do
[true, false].each do |val|
it "sets the allow_http_connections_when_no_cassette to #{val} when set to #{val}" do
16 spec/vcr/request_ignorer_spec.rb
View
@@ -49,6 +49,22 @@ def request(uri)
it_behaves_like "#ignore?", "http://#{host}/foo", false
end
end
+
+ context 'when a custom ignore_request hook has been set' do
+ before(:each) do
+ subject.ignore_request do |request|
+ URI(request.uri).port == 5
+ end
+ end
+
+ it 'ignores requests for which the block returns true' do
+ subject.ignore?(request('http://foo.com:5/bar')).should be_true
+ end
+
+ it 'does not ignore requests for which the block returns false' do
+ subject.ignore?(request('http://foo.com:6/bar')).should be_false
+ end
+ end
end
end
6 spec/vcr/util/hooks_spec.rb
View
@@ -23,6 +23,12 @@
end
describe '#invoke_hook(:before_foo)' do
+ it 'maps the return value of each callback' do
+ subject.before_foo { 17 }
+ subject.before_foo { 12 }
+ subject.invoke_hook(:before_foo).should eq([17, 12])
+ end
+
context 'with a tag argument' do
it 'invokes each of the :before_foo callbacks with a matching tag' do
subject.before_foo(:green) { invocations << :callback_1 }
Please sign in to comment.
Something went wrong with that request. Please try again.