Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: myronmarston/vcr
...
head fork: myronmarston/vcr
  • 16 commits
  • 48 files changed
  • 0 commit comments
  • 1 contributor
Showing with 951 additions and 611 deletions.
  1. +11 −1 CHANGELOG.md
  2. +1 −1  Gemfile
  3. +4 −3 Gemfile.lock
  4. +0 −5 TODO.md
  5. +4 −4 benchmarks/http_stubbing_libraries.rb
  6. +1 −0  features/.nav
  7. +61 −0 features/configuration/ignore_hosts.feature
  8. +34 −0 features/http_libraries/net_http.feature
  9. +16 −1 features/step_definitions/cli_steps.rb
  10. +23 −14 lib/vcr.rb
  11. +2 −4 lib/vcr/cassette.rb
  12. +20 −5 lib/vcr/config.rb
  13. +27 −14 lib/vcr/deprecations.rb
  14. +14 −9 lib/vcr/http_stubbing_adapters/fakeweb.rb
  15. +12 −3 lib/vcr/http_stubbing_adapters/faraday.rb
  16. +3 −7 lib/vcr/http_stubbing_adapters/typhoeus.rb
  17. +17 −7 lib/vcr/http_stubbing_adapters/webmock.rb
  18. +1 −1  lib/vcr/middleware/faraday.rb
  19. +12 −8 lib/vcr/request_matcher.rb
  20. +0 −176 lib/vcr/structs.rb
  21. +16 −0 lib/vcr/structs/http_interaction.rb
  22. +24 −0 lib/vcr/structs/normalizers/body.rb
  23. +56 −0 lib/vcr/structs/normalizers/header.rb
  24. +17 −0 lib/vcr/structs/normalizers/status_message.rb
  25. +34 −0 lib/vcr/structs/normalizers/uri.rb
  26. +20 −0 lib/vcr/structs/request.rb
  27. +16 −0 lib/vcr/structs/response.rb
  28. +9 −0 lib/vcr/structs/response_status.rb
  29. +37 −0 lib/vcr/util/regexes.rb
  30. +16 −5 lib/vcr/version.rb
  31. +26 −3 spec/spec_helper.rb
  32. +11 −12 spec/support/http_library_adapters.rb
  33. +2 −16 spec/support/http_stubbing_adapter.rb
  34. +84 −0 spec/support/normalizers.rb
  35. +1 −1  spec/support/version_checker.rb
  36. +8 −10 spec/vcr/cassette_spec.rb
  37. +63 −17 spec/vcr/config_spec.rb
  38. +83 −24 spec/vcr/deprecations_spec.rb
  39. +1 −1  spec/vcr/http_stubbing_adapters/multi_object_proxy_spec.rb
  40. +2 −2 spec/vcr/http_stubbing_adapters/typhoeus_spec.rb
  41. +1 −1  spec/vcr/middleware/faraday_spec.rb
  42. +23 −0 spec/vcr/structs/http_interaction_spec.rb
  43. +54 −0 spec/vcr/structs/request_spec.rb
  44. +39 −0 spec/vcr/structs/response_spec.rb
  45. +18 −0 spec/vcr/structs/response_status_spec.rb
  46. +0 −201 spec/vcr/structs_spec.rb
  47. +26 −54 spec/vcr_spec.rb
  48. +1 −1  vcr.gemspec
12 CHANGELOG.md
View
@@ -2,7 +2,17 @@
## In git
-[Full Changelog](http://github.com/myronmarston/vcr/compare/v1.5.1...master)
+[Full Changelog](http://github.com/myronmarston/vcr/compare/v1.6.0...master)
+
+## 1.6.0 (February 3, 2011)
+
+[Full Changelog](http://github.com/myronmarston/vcr/compare/v1.5.1...v1.6.0)
+
+* Add new `ignore_hosts` configuration option that allows you to ignore
+ any host (not just localhost aliases, as the `ignore_localhost` option
+ works). Feature suggested by [Claudio Poli](https://github.com/masterkain).
+* Upgraded to the latest Typhoeus (0.2.1).
+* General code clean up and refactoring.
## 1.5.1 (January 12, 2011)
2  Gemfile
View
@@ -7,7 +7,7 @@ group :development do
gem 'patron', '~> 0.4.6'
gem 'em-http-request', '~> 0.2.7'
gem 'curb', '~> 0.7.8'
- gem 'typhoeus', '~> 0.2.0'
+ gem 'typhoeus', '~> 0.2.1'
end
platforms :jruby do
7 Gemfile.lock
View
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- vcr (1.5.1)
+ vcr (1.6.0)
GEM
remote: http://rubygems.org/
@@ -113,7 +113,8 @@ GEM
thor (0.14.6)
tilt (1.1)
timecop (0.3.5)
- typhoeus (0.2.0)
+ typhoeus (0.2.1)
+ mime-types
webmock (1.6.2)
addressable (>= 2.2.2)
crack (>= 0.1.7)
@@ -149,6 +150,6 @@ DEPENDENCIES
shoulda (~> 2.9.2)
sinatra (~> 1.1.0)
timecop (~> 0.3.5)
- typhoeus (~> 0.2.0)
+ typhoeus (~> 0.2.1)
vcr!
webmock (~> 1.6.0)
5 TODO.md
View
@@ -1,5 +0,0 @@
-* Use fakefs gem instead of using temp_dir in specs.
-* Fix #method vs .method in specs.
-* Cuke for Net::HTTP HTTPS request
-* Cuke for multiple simultaneous em-http-request
-* Ensure the checkpoints are properly deep-duped
8 benchmarks/http_stubbing_libraries.rb
View
@@ -50,10 +50,10 @@ def perform_benchmark(name)
# Output on my machine:
#
# Benchmarking Single setup/teardown:
-# webmock 0.000000 0.000000 8.500000 ( 8.559143)
-# fakeweb 0.000000 0.000000 1.900000 ( 1.967160)
+# webmock 0.000000 0.000000 6.950000 ( 6.981525)
+# fakeweb 0.000000 0.010000 1.750000 ( 1.740679)
#
#
# Benchmarking Setup/teardown for each http request:
-# webmock 0.000000 0.000000 9.710000 ( 9.764760)
-# fakeweb 0.000000 0.000000 2.470000 ( 2.479292)
+# webmock 0.000000 0.000000 7.970000 ( 7.981383)
+# fakeweb 0.000000 0.000000 2.210000 ( 2.203478)
1  features/.nav
View
@@ -12,6 +12,7 @@
- cassette_library_dir.feature
- stub_with.feature
- default_cassette_options.feature
+ - ignore_hosts.feature
- ignore_localhost.feature
- hooks.feature
- allow_http_connections_when_no_cassette.feature
61 features/configuration/ignore_hosts.feature
View
@@ -0,0 +1,61 @@
+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:
+ """
+ require 'vcr_cucumber_helpers'
+
+ 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:
+ """
+ require 'vcr_cucumber_helpers'
+ include_http_adapter_for("<http_lib>")
+ require 'sinatra_app.rb'
+
+ require 'vcr'
+
+ VCR.config do |c|
+ c.ignore_hosts '127.0.0.1', 'localhost'
+ c.cassette_library_dir = 'cassettes'
+ c.stub_with <stub_with>
+ end
+
+ VCR.use_cassette('example', :record => :new_episodes) 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:
+ | stub_with | http_lib |
+ | :fakeweb | net/http |
+ | :webmock | net/http |
+ | :webmock | httpclient |
+ | :webmock | patron |
+ | :webmock | curb |
+ | :webmock | em-http-request |
+ | :typhoeus | typhoeus |
+
34 features/http_libraries/net_http.feature
View
@@ -135,3 +135,37 @@ Feature: Net::HTTP
| stub_with |
| :fakeweb |
| :webmock |
+
+ Scenario Outline: Make an HTTPS request
+ Given a file named "vcr_https.rb" with:
+ """
+ require 'vcr'
+
+ VCR.config do |c|
+ c.stub_with <stub_with>
+ c.cassette_library_dir = 'cassettes'
+ end
+
+ uri = URI("https://gist.github.com/raw/fb555cb593f3349d53af/6921dd638337d3f6a51b0e02e7f30e3c414f70d6/vcr_gist")
+
+ VCR.use_cassette('https', :record => :new_episodes) do
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ response = http.request_get(uri.path)
+
+ puts response.body
+ end
+ """
+ When I run "ruby vcr_https.rb"
+ Then the output should contain "VCR gist"
+ And the file "cassettes/https.yml" should contain "body: VCR gist"
+
+ When I modify the file "cassettes/https.yml" to replace "body: VCR gist" with "body: HTTPS replaying works"
+ And I run "ruby vcr_https.rb"
+ Then the output should contain "HTTPS replaying works"
+
+ Examples:
+ | stub_with |
+ | :fakeweb |
+ | :webmock |
17 features/step_definitions/cli_steps.rb
View
@@ -1,4 +1,4 @@
-require 'vcr/structs'
+require 'vcr'
module VCRHelpers
YAML_REGEX_FOR_1_9_1 = Regexp.union(*[
@@ -36,6 +36,17 @@ def normalize_cassette_structs(content)
structs
end
+
+ def modify_file(file_name, orig_text, new_text)
+ in_current_dir do
+ file = File.read(file_name)
+ regex = /#{Regexp.escape(orig_text)}/
+ file.should =~ regex
+
+ file = file.gsub(regex, new_text)
+ File.open(file_name, 'w') { |f| f.write(file) }
+ end
+ end
end
World(VCRHelpers)
@@ -55,6 +66,10 @@ def normalize_cassette_structs(content)
set_env('DAYS_PASSED', day_count)
end
+When /^I modify the file "([^"]*)" to replace "([^"]*)" with "([^"]*)"$/ do |file_name, orig_text, new_text|
+ modify_file(file_name, orig_text, new_text)
+end
+
Then /^the file "([^"]*)" should exist$/ do |file_name|
check_file_presence([file_name], true)
end
37 lib/vcr.rb
View
@@ -2,10 +2,19 @@
require 'vcr/config'
require 'vcr/deprecations'
require 'vcr/request_matcher'
-require 'vcr/structs'
+require 'vcr/util/regexes'
require 'vcr/version'
require 'vcr/http_stubbing_adapters/common'
+require 'vcr/structs/normalizers/body'
+require 'vcr/structs/normalizers/header'
+require 'vcr/structs/normalizers/status_message'
+require 'vcr/structs/normalizers/uri'
+require 'vcr/structs/http_interaction'
+require 'vcr/structs/request'
+require 'vcr/structs/response'
+require 'vcr/structs/response_status'
+
module VCR
extend self
@@ -65,7 +74,7 @@ def config
yield VCR::Config
http_stubbing_adapter.check_version!
http_stubbing_adapter.set_http_connections_allowed_to_default
- http_stubbing_adapter.ignore_localhost = VCR::Config.ignore_localhost?
+ http_stubbing_adapter.ignored_hosts = VCR::Config.ignored_hosts
end
def cucumber_tags(&block)
@@ -79,16 +88,7 @@ def http_stubbing_adapter
raise ArgumentError.new("You have configured VCR to use both :fakeweb and :webmock. You cannot use both.")
end
- adapters = VCR::Config.http_stubbing_libraries.map do |lib|
- case lib
- when :fakeweb; HttpStubbingAdapters::FakeWeb
- when :webmock; HttpStubbingAdapters::WebMock
- when :typhoeus; HttpStubbingAdapters::Typhoeus
- when :faraday; HttpStubbingAdapters::Faraday
- else raise ArgumentError.new("#{lib.inspect} is not a supported HTTP stubbing library.")
- end
- end
-
+ adapters = VCR::Config.http_stubbing_libraries.map { |l| adapter_for(l) }
raise ArgumentError.new("The http stubbing library is not configured.") if adapters.empty?
HttpStubbingAdapters::MultiObjectProxy.for(*adapters)
end
@@ -96,8 +96,7 @@ def http_stubbing_adapter
def record_http_interaction(interaction)
return unless cassette = current_cassette
- return if http_stubbing_adapter.ignore_localhost? &&
- LOCALHOST_ALIASES.include?(URI.parse(interaction.uri).host)
+ return if VCR::Config.uri_should_be_ignored?(interaction.uri)
cassette.record_http_interaction(interaction)
end
@@ -132,6 +131,16 @@ def turned_on?
private
+ def adapter_for(lib)
+ case lib
+ when :fakeweb; HttpStubbingAdapters::FakeWeb
+ when :webmock; HttpStubbingAdapters::WebMock
+ when :typhoeus; HttpStubbingAdapters::Typhoeus
+ when :faraday; HttpStubbingAdapters::Faraday
+ else raise ArgumentError.new("#{lib.inspect} is not a supported HTTP stubbing library.")
+ end
+ end
+
def cassettes
@cassettes ||= []
end
6 lib/vcr/cassette.rb
View
@@ -104,10 +104,8 @@ def load_recorded_interactions
interactions = YAML.load(raw_yaml_content)
invoke_hook(:before_playback, interactions)
- if VCR.http_stubbing_adapter.ignore_localhost?
- interactions.reject! do |i|
- i.uri.is_a?(String) && VCR::LOCALHOST_ALIASES.include?(URI.parse(i.uri).host)
- end
+ interactions.reject! do |i|
+ i.request.uri.is_a?(String) && VCR::Config.uri_should_be_ignored?(i.request.uri)
end
recorded_interactions.replace(interactions)
25 lib/vcr/config.rb
View
@@ -30,13 +30,22 @@ def http_stubbing_libraries
@http_stubbing_libraries ||= []
end
- def ignore_localhost=(value)
- @ignore_localhost = value
- VCR.http_stubbing_adapter.ignore_localhost = value if http_stubbing_libraries.any?
+ def ignore_hosts(*hosts)
+ ignored_hosts.push(*hosts).uniq!
+ VCR.http_stubbing_adapter.ignored_hosts = ignored_hosts if http_stubbing_libraries.any?
+ end
+ alias ignore_host ignore_hosts
+
+ def ignored_hosts
+ @ignored_hosts ||= []
end
- def ignore_localhost?
- @ignore_localhost
+ def ignore_localhost=(value)
+ if value
+ ignore_hosts *VCR::LOCALHOST_ALIASES
+ else
+ ignored_hosts.reject! { |h| VCR::LOCALHOST_ALIASES.include?(h) }
+ end
end
def allow_http_connections_when_no_cassette=(value)
@@ -47,5 +56,11 @@ def allow_http_connections_when_no_cassette=(value)
def allow_http_connections_when_no_cassette?
!!@allow_http_connections_when_no_cassette
end
+
+ def uri_should_be_ignored?(uri)
+ uri = URI.parse(uri) unless uri.respond_to?(:host)
+ ignored_hosts.include?(uri.host)
+ end
end
end
+
41 lib/vcr/deprecations.rb
View
@@ -1,22 +1,33 @@
module VCR
- module Config
- class << self
- def http_stubbing_library
- warn "WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead."
- @http_stubbing_libraries && @http_stubbing_libraries.first
+ module HttpStubbingAdapters
+ module Common
+ def ignore_localhost?
+ VCR::Config.ignore_localhost?
end
+ end
+ end
- def http_stubbing_library=(library)
- warn "WARNING: `VCR::Config.http_stubbing_library = #{library.inspect}` is deprecated. Use `VCR::Config.stub_with #{library.inspect}` instead."
- stub_with library
- end
+ module Config
+ def http_stubbing_library
+ warn "WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead."
+ @http_stubbing_libraries && @http_stubbing_libraries.first
+ end
+
+ def http_stubbing_library=(library)
+ warn "WARNING: `VCR::Config.http_stubbing_library = #{library.inspect}` is deprecated. Use `VCR::Config.stub_with #{library.inspect}` instead."
+ stub_with library
+ end
+
+ def ignore_localhost?
+ warn "WARNING: `VCR::Config.ignore_localhost?` is deprecated. Check the list of ignored hosts using `VCR::Config.ignored_hosts` instead."
+ (VCR::LOCALHOST_ALIASES - ignored_hosts).empty?
end
end
class Cassette
def allow_real_http_requests_to?(uri)
warn "WARNING: VCR::Cassette#allow_real_http_requests_to? is deprecated and should no longer be used."
- VCR.http_stubbing_adapter.ignore_localhost? && VCR::LOCALHOST_ALIASES.include?(uri.host)
+ VCR::Config.uri_should_be_ignored?(uri.to_s)
end
private
@@ -24,8 +35,9 @@ def allow_real_http_requests_to?(uri)
def deprecate_old_cassette_options(options)
message = "VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option."
if options[:allow_real_http] == :localhost
- @original_ignore_localhost = VCR.http_stubbing_adapter.ignore_localhost?
- VCR.http_stubbing_adapter.ignore_localhost = true
+ @original_ignored_hosts = VCR::Config.ignored_hosts.dup
+ VCR::Config.ignored_hosts.clear
+ VCR::Config.ignore_hosts *VCR::LOCALHOST_ALIASES
Kernel.warn "WARNING: #{message}"
elsif options[:allow_real_http]
raise ArgumentError.new(message)
@@ -33,8 +45,9 @@ def deprecate_old_cassette_options(options)
end
def restore_ignore_localhost_for_deprecation
- if defined?(@original_ignore_localhost)
- VCR.http_stubbing_adapter.ignore_localhost = @original_ignore_localhost
+ if defined?(@original_ignored_hosts)
+ VCR::Config.ignored_hosts.clear
+ VCR::Config.ignore_hosts *@original_ignored_hosts
end
end
end
23 lib/vcr/http_stubbing_adapters/fakeweb.rb
View
@@ -8,7 +8,6 @@ module FakeWeb
extend self
UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES = [:body, :headers]
- LOCALHOST_REGEX = %r|\Ahttps?://((\w+:)?\w+@)?(#{VCR::LOCALHOST_ALIASES.map { |a| Regexp.escape(a) }.join('|')})(:\d+)?/|i
MINIMUM_VERSION = '1.3.0'
MAXIMUM_VERSION = '1.3'
@@ -22,15 +21,11 @@ def http_connections_allowed?
!!::FakeWeb.allow_net_connect?("http://some.url/besides/localhost")
end
- def ignore_localhost=(value)
- @ignore_localhost = value
+ def ignored_hosts=(hosts)
+ @ignored_hosts = hosts
update_fakeweb_allow_net_connect
end
- def ignore_localhost?
- !!@ignore_localhost
- end
-
def stub_requests(http_interactions, match_attributes)
validate_match_attributes(match_attributes)
@@ -62,6 +57,10 @@ def request_uri(net_http, request)
private
+ def ignored_hosts
+ @ignored_hosts ||= []
+ end
+
def version
::FakeWeb::VERSION
end
@@ -69,8 +68,8 @@ def version
def update_fakeweb_allow_net_connect
::FakeWeb.allow_net_connect = if @http_connections_allowed
true
- elsif @ignore_localhost
- LOCALHOST_REGEX
+ elsif ignored_hosts.any?
+ VCR::Regexes.url_regex_for_hosts(ignored_hosts)
else
false
end
@@ -93,6 +92,12 @@ def validate_match_attributes(match_attributes)
raise UnsupportedRequestMatchAttributeError.new("FakeWeb does not support matching requests on #{invalid_attributes.join(' or ')}")
end
end
+
+ def self.const_missing(const)
+ return super unless const == :LOCALHOST_REGEX
+ warn "WARNING: `VCR::HttpStubbingAdapters::FakeWeb::LOCALHOST_REGEX` is deprecated."
+ VCR::Regexes.url_regex_for_hosts(VCR::LOCALHOST_ALIASES)
+ end
end
end
end
15 lib/vcr/http_stubbing_adapters/faraday.rb
View
@@ -9,14 +9,19 @@ module Faraday
MINIMUM_VERSION = '0.5.3'
MAXIMUM_VERSION = '0.5'
- attr_writer :http_connections_allowed, :ignore_localhost
+ attr_writer :http_connections_allowed
def http_connections_allowed?
!!@http_connections_allowed
end
- def ignore_localhost?
- !!@ignore_localhost
+ def ignored_hosts=(hosts)
+ @ignored_hosts = hosts
+ end
+
+ def uri_should_be_ignored?(uri)
+ uri = URI.parse(uri) unless uri.respond_to?(:host)
+ ignored_hosts.include?(uri.host)
end
def stub_requests(http_interactions, match_attributes)
@@ -52,6 +57,10 @@ def version
::Faraday::VERSION
end
+ def ignored_hosts
+ @ignored_hosts ||= []
+ end
+
def checkpoints
@checkpoints ||= {}
end
10 lib/vcr/http_stubbing_adapters/typhoeus.rb
View
@@ -6,7 +6,7 @@ module Typhoeus
include VCR::HttpStubbingAdapters::Common
extend self
- MINIMUM_VERSION = '0.2.0'
+ MINIMUM_VERSION = '0.2.1'
MAXIMUM_VERSION = '0.2'
def http_connections_allowed=(value)
@@ -17,12 +17,8 @@ def http_connections_allowed?
!!::Typhoeus::Hydra.allow_net_connect?
end
- def ignore_localhost=(value)
- ::Typhoeus::Hydra.ignore_localhost = value
- end
-
- def ignore_localhost?
- !!::Typhoeus::Hydra.ignore_localhost?
+ def ignored_hosts=(hosts)
+ ::Typhoeus::Hydra.ignore_hosts = hosts
end
def stub_requests(http_interactions, match_attributes)
24 lib/vcr/http_stubbing_adapters/webmock.rb
View
@@ -10,19 +10,17 @@ module WebMock
MAXIMUM_VERSION = '1.6'
def http_connections_allowed=(value)
- ::WebMock::Config.instance.allow_net_connect = value
+ @http_connections_allowed = value
+ update_webmock_allow_net_connect
end
def http_connections_allowed?
!!::WebMock::Config.instance.allow_net_connect
end
- def ignore_localhost=(value)
- ::WebMock::Config.instance.allow_localhost = value
- end
-
- def ignore_localhost?
- !!::WebMock::Config.instance.allow_localhost
+ def ignored_hosts=(hosts)
+ @ignored_hosts = hosts
+ update_webmock_allow_net_connect
end
def stub_requests(http_interactions, match_attributes)
@@ -50,6 +48,18 @@ def version
::WebMock.version
end
+ def ignored_hosts
+ @ignored_hosts ||= []
+ end
+
+ def update_webmock_allow_net_connect
+ if @http_connections_allowed
+ ::WebMock.allow_net_connect!
+ else
+ ::WebMock.disable_net_connect!(:allow => ignored_hosts)
+ end
+ end
+
def request_signature_hash(request_matcher)
signature = {}
signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
2  lib/vcr/middleware/faraday.rb
View
@@ -13,7 +13,7 @@ def call(env)
request = request_for(env)
request_matcher = request.matcher(cassette.match_requests_on)
- if VCR::HttpStubbingAdapters::Faraday.ignore_localhost? && VCR::LOCALHOST_ALIASES.include?(URI.parse(request.uri).host)
+ if VCR::HttpStubbingAdapters::Faraday.uri_should_be_ignored?(request.uri)
@app.call(env)
elsif response = VCR::HttpStubbingAdapters::Faraday.stubbed_response_for(request_matcher)
env.update(
20 lib/vcr/request_matcher.rb
View
@@ -20,21 +20,21 @@ def match_attributes=(attributes)
# for two sets of the same elements unless they are ordered
# the same, so we sort the attributes here.
attributes = attributes.sort { |a, b| a.to_s <=> b.to_s }
- @match_attributes = Set.new(attributes)
+ @match_attributes = set(attributes)
end
def uri
return request.uri unless request.uri.is_a?(String)
uri_matchers = match_attributes.to_a & [:uri, :host, :path]
- case Set.new(uri_matchers)
- when Set.new then /.*/
- when Set.new([:uri]) then request.uri
- when Set.new([:host]) then %r{\Ahttps?://((\w+:)?\w+@)?#{Regexp.escape(URI(request.uri).host)}(:\d+)?/}i
- when Set.new([:path]) then %r{\Ahttps?://[^/]+#{Regexp.escape(URI(request.uri).path)}/?(\?.*)?\z}i
- when Set.new([:host, :path])
+ case set(uri_matchers)
+ when set then /.*/
+ when set(:uri) then request.uri
+ when set(:host) then VCR::Regexes.url_regex_for_hosts([URI(request.uri).host])
+ when set(:path) then VCR::Regexes.url_regex_for_path(URI(request.uri).path)
+ when set(:host, :path)
uri = URI(request.uri)
- %r{\Ahttps?://((\w+:)?\w+@)?#{Regexp.escape(uri.host)}(:\d+)?#{Regexp.escape(uri.path)}/?(\?.*)?\z}i
+ VCR::Regexes.url_regex_for_host_and_path(uri.host, uri.path)
else raise ArgumentError.new("match_attributes cannot include #{uri_matchers.join(' and ')}")
end
end
@@ -74,6 +74,10 @@ def hash
private
+ def set(*elements)
+ Set.new(elements.flatten)
+ end
+
def sorted_header_array
header_hash = headers
return header_hash unless header_hash.is_a?(Hash)
176 lib/vcr/structs.rb
View
@@ -1,176 +0,0 @@
-require 'forwardable'
-
-module VCR
- module BodyNormalizer
- def initialize(*args)
- super
- normalize_body
- end
-
- private
-
- def normalize_body
- # Ensure that the body is a raw string, in case the string instance
- # has been subclassed or extended with additional instance variables
- # or attributes, so that it is serialized to YAML as a raw string.
- # This is needed for rest-client. See this ticket for more info:
- # http://github.com/myronmarston/vcr/issues/4
- self.body = case body
- when nil, ''; nil
- else String.new(body)
- end
- end
- end
-
- module HeaderNormalizer
- # These headers get added by the various HTTP clients automatically,
- # and we don't care about them. We store the headers for the purposes
- # of request matching, and we only care to match on headers users
- # explicitly set.
- HEADERS_TO_SKIP = {
- 'connection' => %w[ close Keep-Alive ],
- 'accept' => %w[ */* ],
- 'expect' => [''],
- 'user-agent' => ["Typhoeus - http://github.com/pauldix/typhoeus/tree/master", 'Ruby']
- }
-
- def initialize(*args)
- super
- normalize_headers
- end
-
- private
-
- def important_header_values(k, values)
- skip_values = HEADERS_TO_SKIP[k] || []
- values - skip_values
- end
-
- def normalize_headers
- new_headers = {}
-
- headers.each do |k, v|
- k = k.downcase
-
- val_array = case v
- when Array then v
- when nil then []
- else [v]
- end
-
- important_vals = important_header_values(k, val_array)
- next unless important_vals.size > 0
-
- # Ensure the values are raw strings.
- # Apparently for Paperclip uploads to S3, headers
- # get serialized with some extra stuff which leads
- # to a seg fault. See this issue for more info:
- # https://github.com/myronmarston/vcr/issues#issue/39
- string_vals = important_vals.map { |v| String.new(v) }
-
- new_headers[k] = string_vals
- end if headers
-
- self.headers = new_headers.empty? ? nil : new_headers
- end
- end
-
- module URINormalizer
- DEFAULT_PORTS = {
- 'http' => 80,
- 'https' => 443
- }
-
- def initialize(*args)
- super
- normalize_uri
- end
-
- private
-
- def normalize_uri
- u = begin
- URI.parse(uri)
- rescue URI::InvalidURIError
- return
- end
-
- u.port ||= DEFAULT_PORTS[u.scheme]
-
- # URI#to_s only includes the port if it's not the default
- # but we want to always include it (since FakeWeb/WebMock
- # urls have always included it). We force it to be included
- # here by redefining default_port so that URI#to_s will include it.
- def u.default_port; nil; end
- self.uri = u.to_s
- end
- end
-
- module StatusMessageNormalizer
- def initialize(*args)
- super
- normalize_status_message
- end
-
- private
-
- def normalize_status_message
- self.message = message.strip if message
- self.message = nil if message == ''
- end
- end
-
- class Request < Struct.new(:method, :uri, :body, :headers)
- include HeaderNormalizer
- include URINormalizer
- include BodyNormalizer
-
- def self.from_net_http_request(net_http, request)
- new(
- request.method.downcase.to_sym,
- VCR.http_stubbing_adapter.request_uri(net_http, request),
- request.body,
- request.to_hash
- )
- end
-
- def matcher(match_attributes)
- RequestMatcher.new(self, match_attributes)
- end
- end
-
- class ResponseStatus < Struct.new(:code, :message)
- include StatusMessageNormalizer
-
- def self.from_net_http_response(response)
- new(response.code.to_i, response.message)
- end
- end
-
- class Response < Struct.new(:status, :headers, :body, :http_version)
- include HeaderNormalizer
- include BodyNormalizer
-
- def self.from_net_http_response(response)
- new(
- ResponseStatus.from_net_http_response(response),
- response.to_hash,
- response.body,
- response.http_version
- )
- end
- end
-
- class HTTPInteraction < Struct.new(:request, :response)
- extend ::Forwardable
- def_delegators :request, :uri, :method
-
- def ignore!
- @ignored = true
- end
-
- def ignored?
- @ignored
- end
- end
-end
16 lib/vcr/structs/http_interaction.rb
View
@@ -0,0 +1,16 @@
+require 'forwardable'
+
+module VCR
+ class HTTPInteraction < Struct.new(:request, :response)
+ extend ::Forwardable
+ def_delegators :request, :uri, :method
+
+ def ignore!
+ @ignored = true
+ end
+
+ def ignored?
+ @ignored
+ end
+ end
+end
24 lib/vcr/structs/normalizers/body.rb
View
@@ -0,0 +1,24 @@
+module VCR
+ module Normalizers
+ module Body
+ def initialize(*args)
+ super
+ normalize_body
+ end
+
+ private
+
+ def normalize_body
+ # Ensure that the body is a raw string, in case the string instance
+ # has been subclassed or extended with additional instance variables
+ # or attributes, so that it is serialized to YAML as a raw string.
+ # This is needed for rest-client. See this ticket for more info:
+ # http://github.com/myronmarston/vcr/issues/4
+ self.body = case body
+ when nil, ''; nil
+ else String.new(body)
+ end
+ end
+ end
+ end
+end
56 lib/vcr/structs/normalizers/header.rb
View
@@ -0,0 +1,56 @@
+module VCR
+ module Normalizers
+ module Header
+ # These headers get added by the various HTTP clients automatically,
+ # and we don't care about them. We store the headers for the purposes
+ # of request matching, and we only care to match on headers users
+ # explicitly set.
+ HEADERS_TO_SKIP = {
+ 'connection' => %w[ close Keep-Alive ],
+ 'accept' => %w[ */* ],
+ 'expect' => [''],
+ 'user-agent' => ["Typhoeus - http://github.com/dbalatero/typhoeus/tree/master", 'Ruby']
+ }
+
+ def initialize(*args)
+ super
+ normalize_headers
+ end
+
+ private
+
+ def important_header_values(k, values)
+ skip_values = HEADERS_TO_SKIP[k] || []
+ values - skip_values
+ end
+
+ def normalize_headers
+ new_headers = {}
+
+ headers.each do |k, v|
+ k = k.downcase
+
+ val_array = case v
+ when Array then v
+ when nil then []
+ else [v]
+ end
+
+ important_vals = important_header_values(k, val_array)
+ next unless important_vals.size > 0
+
+ # Ensure the values are raw strings.
+ # Apparently for Paperclip uploads to S3, headers
+ # get serialized with some extra stuff which leads
+ # to a seg fault. See this issue for more info:
+ # https://github.com/myronmarston/vcr/issues#issue/39
+ string_vals = important_vals.map { |v| String.new(v) }
+
+ new_headers[k] = string_vals
+ end if headers
+
+ self.headers = new_headers.empty? ? nil : new_headers
+ end
+ end
+ end
+end
17 lib/vcr/structs/normalizers/status_message.rb
View
@@ -0,0 +1,17 @@
+module VCR
+ module Normalizers
+ module StatusMessage
+ def initialize(*args)
+ super
+ normalize_status_message
+ end
+
+ private
+
+ def normalize_status_message
+ self.message = message.strip if message
+ self.message = nil if message == ''
+ end
+ end
+ end
+end
34 lib/vcr/structs/normalizers/uri.rb
View
@@ -0,0 +1,34 @@
+module VCR
+ module Normalizers
+ module URI
+ DEFAULT_PORTS = {
+ 'http' => 80,
+ 'https' => 443
+ }
+
+ def initialize(*args)
+ super
+ normalize_uri
+ end
+
+ private
+
+ def normalize_uri
+ u = begin
+ ::URI.parse(uri)
+ rescue ::URI::InvalidURIError
+ return
+ end
+
+ u.port ||= DEFAULT_PORTS[u.scheme]
+
+ # URI#to_s only includes the port if it's not the default
+ # but we want to always include it (since FakeWeb/WebMock
+ # urls have always included it). We force it to be included
+ # here by redefining default_port so that URI#to_s will include it.
+ def u.default_port; nil; end
+ self.uri = u.to_s
+ end
+ end
+ end
+end
20 lib/vcr/structs/request.rb
View
@@ -0,0 +1,20 @@
+module VCR
+ class Request < Struct.new(:method, :uri, :body, :headers)
+ include Normalizers::Header
+ include Normalizers::URI
+ include Normalizers::Body
+
+ def self.from_net_http_request(net_http, request)
+ new(
+ request.method.downcase.to_sym,
+ VCR.http_stubbing_adapter.request_uri(net_http, request),
+ request.body,
+ request.to_hash
+ )
+ end
+
+ def matcher(match_attributes)
+ RequestMatcher.new(self, match_attributes)
+ end
+ end
+end
16 lib/vcr/structs/response.rb
View
@@ -0,0 +1,16 @@
+module VCR
+ class Response < Struct.new(:status, :headers, :body, :http_version)
+ include Normalizers::Header
+ include Normalizers::Body
+
+ def self.from_net_http_response(response)
+ new(
+ ResponseStatus.from_net_http_response(response),
+ response.to_hash,
+ response.body,
+ response.http_version
+ )
+ end
+ end
+end
+
9 lib/vcr/structs/response_status.rb
View
@@ -0,0 +1,9 @@
+module VCR
+ class ResponseStatus < Struct.new(:code, :message)
+ include Normalizers::StatusMessage
+
+ def self.from_net_http_response(response)
+ new(response.code.to_i, response.message)
+ end
+ end
+end
37 lib/vcr/util/regexes.rb
View
@@ -0,0 +1,37 @@
+module VCR
+ module Regexes
+ extend self
+
+ PROTOCOL = '\Ahttps?://'
+ CREDENTIALS = '((\w+:)?\w+@)?'
+ PORT = '(:\d+)?'
+ THE_REST = '/?(\?.*)?\z'
+
+ @@url_host_regexes = Hash.new do |hash, hosts|
+ hash[hosts] = begin
+ host_regex = hosts.map { |h| Regexp.escape(h) }.join('|')
+ %r|#{PROTOCOL}#{CREDENTIALS}(#{host_regex})#{PORT}/|i
+ end
+ end
+
+ def url_regex_for_hosts(hosts)
+ @@url_host_regexes[hosts.sort]
+ end
+
+ @@url_path_regexes = Hash.new do |hash, path|
+ %r|#{PROTOCOL}[^/]+#{Regexp.escape(path)}#{THE_REST}|i
+ end
+
+ def url_regex_for_path(path)
+ @@url_path_regexes[path]
+ end
+
+ @@url_host_and_path_regexes = Hash.new do |hash, (host, path)|
+ %r|#{PROTOCOL}#{CREDENTIALS}#{Regexp.escape(host)}#{PORT}#{Regexp.escape(path)}#{THE_REST}|i
+ end
+
+ def url_regex_for_host_and_path(host, path)
+ @@url_host_and_path_regexes[[host, path]]
+ end
+ end
+end
21 lib/vcr/version.rb
View
@@ -3,12 +3,23 @@ module VCR
def version
@version ||= begin
- string = '1.5.1'
+ string = '1.6.0'
- def string.parts; VCR.version.split('.').map { |p| p.to_i }; end
- def string.major; parts[0]; end
- def string.minor; parts[1]; end
- def string.patch; parts[2]; end
+ def string.parts
+ split('.').map { |p| p.to_i }
+ end
+
+ def string.major
+ parts[0]
+ end
+
+ def string.minor
+ parts[1]
+ end
+
+ def string.patch
+ parts[2]
+ end
string
end
29 spec/spec_helper.rb
View
@@ -14,6 +14,25 @@
module VCR
SPEC_ROOT = File.dirname(__FILE__)
+
+ module Config
+ def reset!(stubbing_lib = :fakeweb)
+ self.default_cassette_options = { :record => :new_episodes }
+
+ if stubbing_lib
+ stub_with stubbing_lib
+ else
+ http_stubbing_libraries.clear
+ end
+
+ clear_hooks
+ @ignored_hosts = []
+
+ VCR.instance_eval do
+ instance_variables.each { |ivar| remove_instance_variable(ivar) }
+ end
+ end
+ end
end
RSpec.configure do |config|
@@ -29,9 +48,7 @@ module VCR
VCR.turn_on! unless VCR.turned_on?
VCR.eject_cassette while VCR.current_cassette
- VCR::Config.default_cassette_options = { :record => :new_episodes }
- VCR::Config.stub_with :fakeweb
- VCR::Config.clear_hooks
+ VCR::Config.reset!
WebMock.allow_net_connect!
WebMock.reset!
@@ -42,6 +59,12 @@ module VCR
VCR::HttpStubbingAdapters::Faraday.reset!
end
+ config.after(:each) do
+ VCR::HttpStubbingAdapters::Common.adapters.each do |a|
+ a.ignored_hosts = []
+ end
+ end
+
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
23 spec/support/http_library_adapters.rb
View
@@ -340,7 +340,7 @@ def test_request_stubbed(method, url, expected)
end
[true, false].each do |http_allowed|
- context "when #http_connections_allowed is set to #{http_allowed}" do
+ context "when http_connections_allowed is set to #{http_allowed}" do
before(:each) { subject.http_connections_allowed = http_allowed }
it "returns #{http_allowed} for #http_connections_allowed?" do
@@ -350,25 +350,24 @@ def test_request_stubbed(method, url, expected)
test_real_http_request(http_allowed, *other)
unless http_allowed
- describe '.ignore_localhost =' do
- localhost_response = "Localhost response"
+ localhost_response = "Localhost response"
+
+ describe '.ignore_hosts' do
let(:record_mode) { :none }
- VCR::LOCALHOST_ALIASES.each do |localhost_alias|
- describe 'when set to true' do
- before(:each) { subject.ignore_localhost = true }
+ context 'when set to ["127.0.0.1", "localhost"]' do
+ before(:each) do
+ subject.ignored_hosts = ["127.0.0.1", "localhost"]
+ end
+ %w[ 127.0.0.1 localhost ].each do |localhost_alias|
it "allows requests to #{localhost_alias}" do
get_body_string(make_http_request(:get, "http://#{localhost_alias}:#{VCR::SinatraApp.port}/localhost_test")).should == localhost_response
end
end
- describe 'when set to false' do
- before(:each) { subject.ignore_localhost = false }
-
- it "does not allow requests to #{localhost_alias}" do
- expect { make_http_request(:get, "http://#{localhost_alias}:#{VCR::SinatraApp.port}/localhost_test") }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
- end
+ it 'does not allow requests to 0.0.0.0' do
+ expect { make_http_request(:get, "http://0.0.0.0:#{VCR::SinatraApp.port}/localhost_test") }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
end
end
end
18 spec/support/http_stubbing_adapter.rb
View
@@ -3,20 +3,6 @@
before(:each) { VCR.stub!(:http_stubbing_adapter).and_return(subject) }
subject { described_class }
- describe '.ignore_localhost?' do
- [true, false].each do |val|
- it "returns #{val} when ignore_localhost is set to #{val}" do
- subject.ignore_localhost = val
- subject.ignore_localhost?.should == val
- end
- end
-
- it "returns false when ignore_localhost is set to nil" do
- subject.ignore_localhost = nil
- subject.ignore_localhost?.should == false
- end
- end
-
describe '.set_http_connections_allowed_to_default' do
[true, false].each do |default|
context "when VCR::Config.allow_http_connections_when_no_cassette is #{default}" do
@@ -59,7 +45,7 @@ def adapter_enabled?(adapter)
end
if other.include?(:needs_net_http_extension)
- describe '#request_uri' do
+ describe '.request_uri' do
it 'returns the uri for the given http request' do
net_http = Net::HTTP.new('example.com', 80)
request = Net::HTTP::Get.new('/foo/bar')
@@ -74,7 +60,7 @@ def adapter_enabled?(adapter)
end
end
- describe '#request_stubbed? using specific match_attributes' do
+ describe '.request_stubbed? using specific match_attributes' do
let(:interactions) { YAML.load(File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', YAML_SERIALIZATION_VERSION, 'match_requests_on.yml'))) }
@supported_request_match_attributes = supported_request_match_attributes
84 spec/support/normalizers.rb
View
@@ -0,0 +1,84 @@
+require 'spec_helper'
+
+shared_examples_for "header normalization" do
+ let(:instance) do
+ with_headers('Some_Header' => 'value1', 'aNother' => ['a', 'b'], 'third' => [], 'fourth' => nil)
+ end
+
+ it 'normalizes the hash to lower case keys and arrays of values' do
+ instance.headers['some_header'].should == ['value1']
+ instance.headers['another'].should == ['a', 'b']
+ end
+
+ it 'removes empty headers' do
+ instance.headers.should_not have_key('third')
+ instance.headers.should_not have_key('fourth')
+ end
+
+ it 'filters out unimportant default values set by the HTTP library' do
+ instance = with_headers('accept' => ['*/*'], 'connection' => 'close', 'http-user' => ['foo'], 'expect' => ['', 'bar'])
+ instance.headers.should == { 'http-user' => ['foo'], 'expect' => ['bar'] }
+ end
+
+ it 'sets empty hash header to nil' do
+ with_headers({}).headers.should be_nil
+ end
+
+ it 'ensures header keys are serialized to yaml as raw strings' do
+ key = 'my-key'
+ key.instance_variable_set(:@foo, 7)
+ instance = with_headers(key => ['value1'])
+ instance.headers.to_yaml.should == { 'my-key' => ['value1'] }.to_yaml
+ end
+
+ it 'ensures header values are serialized to yaml as raw strings' do
+ value = 'my-value'
+ value.instance_variable_set(:@foo, 7)
+ instance = with_headers('my-key' => [value])
+ instance.headers.to_yaml.should == { 'my-key' => ['my-value'] }.to_yaml
+ end
+end
+
+shared_examples_for "body normalization" do
+ it 'sets empty string to nil' do
+ instance('').body.should be_nil
+ end
+
+ it "ensures the body is serialized to yaml as a raw string" do
+ body = "My String"
+ body.instance_variable_set(:@foo, 7)
+ instance(body).body.to_yaml.should == "My String".to_yaml
+ end
+end
+
+shared_examples_for 'uri normalization' do
+ it 'adds port 80 to an http URI that lacks a port' do
+ instance('http://example.com/foo').uri.should == 'http://example.com:80/foo'
+ end
+
+ it 'keeps the existing port for an http URI' do
+ instance('http://example.com:8000/foo').uri.should == 'http://example.com:8000/foo'
+ end
+
+ it 'adds port 443 to an https URI that lacks a port' do
+ instance('https://example.com/foo').uri.should == 'https://example.com:443/foo'
+ end
+
+ it 'keeps the existing port for an https URI' do
+ instance('https://example.com:8000/foo').uri.should == 'https://example.com:8000/foo'
+ end
+end
+
+shared_examples_for 'status message normalization' do
+ it 'chomps leading and trailing spaces on the status message' do
+ instance(' OK ').message.should == 'OK'
+ end
+
+ it 'sets status message to nil when it is the empty string' do
+ instance('').message.should be_nil
+ end
+
+ it 'sets status message to nil when it is a blank string' do
+ instance(' ').message.should be_nil
+ end
+end
2  spec/support/version_checker.rb
View
@@ -1,7 +1,7 @@
shared_examples_for "version checking" do |options|
library = described_class.library_name
- describe '#check_version!' do
+ describe '.check_version!' do
options[:valid].each do |version|
it "does nothing when #{library}'s version is #{version}" do
stub_version(version)
18 spec/vcr/cassette_spec.rb
View
@@ -49,7 +49,7 @@
end
end
- describe 'on creation' do
+ describe '.new' do
it 'raises an error with a helpful message when loading an old unsupported cassette' do
VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}"
expect { VCR::Cassette.new('0_3_1_cassette') }.to raise_error(/The VCR cassette 0_3_1_cassette.yml uses an old format that is now deprecated/)
@@ -181,16 +181,14 @@
VCR::Cassette.new(:name, :record => record_mode)
end
- [true, false].each do |ignore_localhost|
- expected_uri_hosts = %w(example.com)
- expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost
-
- it "#{ ignore_localhost ? 'does not load' : 'loads' } localhost interactions from the cassette file when http_stubbing_adapter.ignore_localhost is set to #{ignore_localhost}" do
- VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost)
- VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
- cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
- cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
+ it 'does not load ignored interactions' do
+ VCR::Config.stub(:uri_should_be_ignored?) do |uri|
+ uri.to_s !~ /example\.com/
end
+
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
+ cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
+ cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should == %w[example.com]
end
it "loads the recorded interactions from the library yml file" do
80 spec/vcr/config_spec.rb
View
@@ -6,7 +6,7 @@ def stub_no_http_stubbing_adapter
VCR::Config.stub(:http_stubbing_libraries).and_return([])
end
- describe '#cassette_library_dir=' do
+ describe '.cassette_library_dir=' do
temp_dir(File.expand_path(File.dirname(__FILE__) + '/fixtures/config_spec'))
it 'creates the directory if it does not exist' do
@@ -18,7 +18,7 @@ def stub_no_http_stubbing_adapter
end
end
- describe '#default_cassette_options' do
+ describe '.default_cassette_options' do
it 'has a hash with some defaults even if it is set to nil' do
VCR::Config.default_cassette_options = nil
VCR::Config.default_cassette_options.should == { :match_requests_on => VCR::RequestMatcher::DEFAULT_MATCH_ATTRIBUTES }
@@ -47,26 +47,52 @@ def stub_no_http_stubbing_adapter
end
end
- describe '#ignore_localhost' do
- it 'sets VCR.http_stubbing_adapter.ignore_localhost?' do
- [true, false].each do |val|
- VCR.http_stubbing_adapter.ignore_localhost = !val
- expect {
- VCR::Config.ignore_localhost = val
- }.to change { VCR.http_stubbing_adapter.ignore_localhost? }.from(!val).to(val)
- end
+ describe '.ignore_hosts' do
+ let(:stubbing_adapter) { VCR::HttpStubbingAdapters::FakeWeb }
+ before(:each) do
+ stubbing_adapter.send(:ignored_hosts).should be_empty
+ VCR.stub(:http_stubbing_adapter => stubbing_adapter)
+ VCR::Config.ignored_hosts.should be_empty
end
- it 'stores the value even when VCR.http_stubbing_adapter is not set' do
- stub_no_http_stubbing_adapter
- [true, false].each do |val|
- VCR::Config.ignore_localhost = val
- VCR::Config.ignore_localhost?.should == val
- end
+ it 'adds the given hosts to the ignored_hosts list' do
+ VCR::Config.ignore_hosts 'example.com', 'example.net'
+ VCR::Config.ignored_hosts.should == %w[ example.com example.net ]
+ VCR::Config.ignore_host 'example.org'
+ VCR::Config.ignored_hosts.should == %w[ example.com example.net example.org ]
+ end
+
+ it 'removes duplicate hosts' do
+ VCR::Config.ignore_host 'example.com'
+ VCR::Config.ignore_host 'example.com'
+ VCR::Config.ignored_hosts.should == ['example.com']
+ end
+
+ it "updates the http_stubbing_adapter's ignored_hosts list" do
+ VCR::Config.ignore_hosts 'example.com', 'example.org'
+ stubbing_adapter.send(:ignored_hosts).should == %w[ example.com example.org ]
+ end
+ end
+
+ describe '.ignore_localhost=' do
+ before(:each) do
+ VCR::Config.ignored_hosts.should be_empty
+ end
+
+ it 'adds the localhost aliases to the ignored_hosts list when set to true' do
+ VCR::Config.ignore_host 'example.com'
+ VCR::Config.ignore_localhost = true
+ VCR::Config.ignored_hosts.should == ['example.com', *VCR::LOCALHOST_ALIASES]
+ end
+
+ it 'removes the localhost aliases from the ignored_hosts list when set to false' do
+ VCR::Config.ignore_host 'example.com', *VCR::LOCALHOST_ALIASES
+ VCR::Config.ignore_localhost = false
+ VCR::Config.ignored_hosts.should == ['example.com']
end
end
- describe '#allow_http_connections_when_no_cassette=' do
+ 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
VCR::Config.allow_http_connections_when_no_cassette = val
@@ -85,4 +111,24 @@ def stub_no_http_stubbing_adapter
VCR::Config.allow_http_connections_when_no_cassette = true
end
end
+
+ describe '.uri_should_be_ignored?' do
+ before(:each) { described_class.ignore_hosts 'example.com' }
+
+ it 'returns true for a string URI with a host in the ignore_hosts list' do
+ described_class.uri_should_be_ignored?("http://example.com/").should be_true
+ end
+
+ it 'returns true for a URI instance with a host in the ignore_hosts list' do
+ described_class.uri_should_be_ignored?(URI("http://example.com/")).should be_true
+ end
+
+ it 'returns false for a string URI with a host in the ignore_hosts list' do
+ described_class.uri_should_be_ignored?("http://example.net/").should be_false
+ end
+
+ it 'returns false for a URI instance with a host in the ignore_hosts list' do
+ described_class.uri_should_be_ignored?(URI("http://example.net/")).should be_false
+ end
+ end
end
107 spec/vcr/deprecations_spec.rb
View
@@ -1,8 +1,58 @@
require 'spec_helper'
+shared_examples_for '.ignore_localhost? deprecation' do
+ it 'returns false when no hosts are ignored' do
+ VCR::Config.ignored_hosts.should be_empty
+ described_class.ignore_localhost?.should be_false
+ end
+
+ it 'returns false when only non-local hosts are ignored' do
+ VCR::Config.ignore_hosts 'example.com'
+ described_class.ignore_localhost?.should be_false
+ end
+
+ it 'returns false when only some localhost aliases are ignored' do
+ aliases = VCR::LOCALHOST_ALIASES.dup
+ aliases.pop
+ VCR::Config.ignore_hosts *aliases
+ described_class.ignore_localhost?.should be_false
+ end
+
+ it 'returns true when all localhost aliases are ignored, even if some other hosts are ignored, too' do
+ VCR::Config.ignore_hosts 'example.com', *VCR::LOCALHOST_ALIASES
+ described_class.ignore_localhost?.should be_true
+ end
+
+ it 'prints a warning: WARNING: `VCR::Config.ignore_localhost?` is deprecated. Check the list of ignored hosts using `VCR::Config.ignored_hosts` instead.' do
+ VCR::Config.should_receive(:warn).with(/Check the list of ignored hosts using `VCR::Config.ignored_hosts` instead/)
+ described_class.ignore_localhost?
+ end
+end
+
describe 'Deprecations' do
disable_warnings
+ VCR::HttpStubbingAdapters::Common.adapters.each do |adapter|
+ describe adapter do
+ it_behaves_like '.ignore_localhost? deprecation'
+ end
+ end
+
+ describe VCR::HttpStubbingAdapters::FakeWeb do
+ describe 'LOCALHOST_REGEX constant' do
+ subject { described_class::LOCALHOST_REGEX }
+
+ it 'refers to the expected regex' do
+ should == %r|\Ahttps?://((\w+:)?\w+@)?(#{VCR::LOCALHOST_ALIASES.sort.map { |a| Regexp.escape(a) }.join('|')})(:\d+)?/|i
+ end
+
+ it 'prints a warning: WARNING: `VCR::HttpStubbingAdapters::FakeWeb::LOCALHOST_REGEX` is deprecated.' do
+ described_class.should_receive(:warn).with("WARNING: `VCR::HttpStubbingAdapters::FakeWeb::LOCALHOST_REGEX` is deprecated.")
+ subject
+ end
+ end
+ end
+
describe VCR::Config do
describe '.http_stubbing_library' do
before(:each) { described_class.stub_with :webmock, :typhoeus }
@@ -28,6 +78,8 @@
described_class.http_stubbing_library = :webmock
end
end
+
+ it_behaves_like '.ignore_localhost? deprecation'
end
describe VCR::Cassette do
@@ -43,35 +95,42 @@
end
[true, false].each do |orig_ignore_localhost|
- context "when the http_stubbing_adapter's ignore_localhost is set to #{orig_ignore_localhost}" do
- before(:each) { VCR.http_stubbing_adapter.ignore_localhost = orig_ignore_localhost }
+ orig_ignored_hosts = if orig_ignore_localhost
+ VCR::LOCALHOST_ALIASES
+ else
+ []
+ end
- context 'when the :allow_real_http option is set to :localhost' do
- subject { VCR::Cassette.new('cassette name', :allow_real_http => :localhost) }
+ context "when the ignored_hosts list is set to #{orig_ignored_hosts.inspect} and the :allow_real_http option is set to :localhost" do
+ before(:each) do
+ VCR::Config.ignored_hosts.clear
+ VCR::Config.ignore_hosts *orig_ignored_hosts
+ end
- it "sets the http_stubbing_adapter's ignore_localhost attribute to true" do
- subject
- VCR.http_stubbing_adapter.ignore_localhost?.should == true
- end
+ subject { VCR::Cassette.new('cassette name', :allow_real_http => :localhost) }
- it "prints a warning: VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option." do
- Kernel.should_receive(:warn).with("WARNING: VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option.")
- subject
- end
+ it "sets the ignored_hosts list to the list of localhost aliases" do
+ subject
+ VCR::Config.ignored_hosts.should == VCR::LOCALHOST_ALIASES
+ end
- it "reverts ignore_localhost when the cassette is ejected" do
- subject.eject
- VCR.http_stubbing_adapter.ignore_localhost?.should == orig_ignore_localhost
- end
+ it "prints a warning: VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option." do
+ Kernel.should_receive(:warn).with("WARNING: VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option.")
+ subject
+ end
+
+ it "reverts ignore_hosts when the cassette is ejected" do
+ subject.eject
+ VCR::Config.ignored_hosts.should == orig_ignored_hosts
+ end
- {
- 'http://localhost' => true,
- 'http://127.0.0.1' => true,
- 'http://example.com' => false
- }.each do |url, expected_value|
- it "returns #{expected_value} for #allow_real_http_requests_to? when it is given #{url}" do
- subject.allow_real_http_requests_to?(URI.parse(url)).should == expected_value
- end
+ {
+ 'http://localhost' => true,
+ 'http://127.0.0.1' => true,
+ 'http://example.com' => false
+ }.each do |url, expected_value|
+ it "returns #{expected_value} for #allow_real_http_requests_to? when it is given #{url}" do
+ subject.allow_real_http_requests_to?(URI.parse(url)).should == expected_value
end
end
end
2  spec/vcr/http_stubbing_adapters/multi_object_proxy_spec.rb
View
@@ -20,7 +20,7 @@ module HttpStubbingAdapters
inst_methods.should_not include(:send, :object_id, :__id__)
end
- describe '#proxies_objects' do
+ describe '#proxied_objects' do
it 'returns the proxied objects' do
subject.proxied_objects.should == [mock1, mock2]
end
4 spec/vcr/http_stubbing_adapters/typhoeus_spec.rb
View
@@ -11,8 +11,8 @@
it_behaves_like 'an http stubbing adapter', ['typhoeus'], [:method, :uri, :host, :path, :body, :headers]
it_performs('version checking',
- :valid => %w[ 0.2.0 0.2.99 ],
- :too_low => %w[ 0.1.0 0.1.31 ],
+ :valid => %w[ 0.2.1 0.2.99 ],
+ :too_low => %w[ 0.1.0 0.1.31 0.2.0 ],
:too_high => %w[ 0.3.0 1.0.0 ]
) do
disable_warnings
2  spec/vcr/middleware/faraday_spec.rb
View
@@ -13,7 +13,7 @@
let(:env_hash) { { :url => 'http://localhost:3000/' } }
before(:each) do
- VCR::HttpStubbingAdapters::Faraday.ignore_localhost = true
+ VCR::HttpStubbingAdapters::Faraday.ignored_hosts = ['localhost']
end
it 'uses a cassette when the app is called' do
23 spec/vcr/structs/http_interaction_spec.rb
View
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe VCR::HTTPInteraction do
+ %w( uri method ).each do |attr|
+ it "delegates :#{attr} to the request signature" do
+ sig = mock('request signature')
+ sig.should_receive(attr).and_return(:the_value)
+ instance = described_class.new(sig, nil)
+ instance.send(attr).should == :the_value
+ end
+ end
+
+ describe '#ignored?' do
+ it 'returns false by default' do
+ should_not be_ignored
+ end
+
+ it 'returns true when #ignore! has been called' do
+ subject.ignore!
+ should be_ignored
+ end
+ end
+end
54 spec/vcr/structs/request_spec.rb
View
@@ -0,0 +1,54 @@
+require 'spec_helper'
+
+describe VCR::Request do
+ describe '#matcher' do
+ it 'returns a matcher with the given request' do
+ req = VCR::Request.new
+ req.matcher([:uri]).request.should == req
+ end
+
+ it 'returns a matcher with the given match_attributes' do
+ req = VCR::Request.new
+ req.matcher([:uri, :headers]).match_attributes.to_a.should =~ [:uri, :headers]
+ end
+ end
+
+ describe '.from_net_http_request' do
+ let(:net_http) { YAML.load(File.read("#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/example_net_http.yml")) }
+ let(:request) { YAML.load(File.read("#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/example_net_http_request.yml")) }
+ subject { described_class.from_net_http_request(net_http, request) }
+
+ before(:each) do
+ VCR.http_stubbing_adapter.should respond_to(:request_uri)
+ VCR.http_stubbing_adapter.stub!(:request_uri)
+ end
+
+ it { should be_instance_of(VCR::Request) }
+ its(:method) { should == :post }
+ its(:body) { should == 'id=7' }
+ its(:headers) { should == { "content-type" => ["application/x-www-form-urlencoded"] } }
+
+ it 'sets the uri using the http_stubbing_adapter.request_uri' do
+ VCR.http_stubbing_adapter.should_receive(:request_uri).with(net_http, request).and_return('foo/bar')
+ subject.uri.should == 'foo/bar'
+ end
+ end
+
+ it_performs 'uri normalization' do
+ def instance(uri)
+ VCR::Request.new(:get, uri, '', {})
+ end
+ end
+
+ it_performs 'header normalization' do
+ def with_headers(headers)
+ described_class.new(:get, 'http://example.com/', nil, headers)
+ end
+ end
+