Skip to content

Commit

Permalink
Use the new HTTPInteractionList rather than stubbing requests on the …
Browse files Browse the repository at this point in the history
…HTTP Stubbing Adapter.

This allows us to remove the RequestMatcher and Regexes classes since
they are no longer used.
  • Loading branch information
myronmarston committed Sep 24, 2011
1 parent 7f92317 commit 8ddc4a2
Show file tree
Hide file tree
Showing 23 changed files with 104 additions and 664 deletions.
7 changes: 5 additions & 2 deletions lib/vcr.rb
@@ -1,10 +1,8 @@
require 'vcr/util/regexes'
require 'vcr/util/variable_args_block_caller'
require 'vcr/util/yaml'

require 'vcr/cassette'
require 'vcr/configuration'
require 'vcr/request_matcher'
require 'vcr/request_matcher_registry'
require 'vcr/version'

Expand Down Expand Up @@ -70,6 +68,11 @@ def use_cassette(*args, &block)
end
end

def http_interactions
return current_cassette.http_interactions if current_cassette
VCR::Cassette::HTTPInteractionList::NullList.new
end

def request_matcher_registry
@request_matcher_registry ||= RequestMatcherRegistry.new
end
Expand Down
19 changes: 6 additions & 13 deletions lib/vcr/cassette.rb
Expand Up @@ -3,12 +3,13 @@
require 'set'

require 'vcr/cassette/reader'
require 'vcr/cassette/http_interaction_list'

module VCR
class Cassette
VALID_RECORD_MODES = [:all, :none, :new_episodes, :once]

attr_reader :name, :record_mode, :match_requests_on, :erb, :re_record_interval, :tag
attr_reader :name, :record_mode, :match_requests_on, :erb, :re_record_interval, :tag, :http_interactions

def initialize(name, options = {})
options = VCR.configuration.default_cassette_options.merge(options)
Expand Down Expand Up @@ -42,7 +43,6 @@ def initialize(name, options = {})

def eject
write_recorded_interactions_to_disk
VCR.http_stubbing_adapter.restore_stubs_checkpoint(self)
restore_http_connections_allowed
end

Expand Down Expand Up @@ -111,7 +111,6 @@ def restore_http_connections_allowed
end

def load_recorded_interactions
VCR.http_stubbing_adapter.create_stubs_checkpoint(self)
if file && File.size?(file)
interactions = VCR::YAML.load(raw_yaml_content)

Expand All @@ -128,9 +127,8 @@ def load_recorded_interactions
recorded_interactions.replace(interactions)
end

if should_stub_requests?
VCR.http_stubbing_adapter.stub_requests(recorded_interactions, match_requests_on)
end
interactions = should_stub_requests? ? recorded_interactions : []
@http_interactions = HTTPInteractionList.new(interactions, match_requests_on, VCR.http_interactions)
end

def raw_yaml_content
Expand All @@ -141,14 +139,9 @@ def merged_interactions
old_interactions = recorded_interactions

if should_remove_matching_existing_interactions?
match_attributes = match_requests_on

new_request_matchers = Set.new new_recorded_interactions.map do |i|
i.request.matcher(match_attributes)
end

new_interaction_list = HTTPInteractionList.new(new_recorded_interactions, match_requests_on)
old_interactions = old_interactions.reject do |i|
new_request_matchers.include?(i.request.matcher(match_attributes))
new_interaction_list.has_interaction_matching?(i.request)
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/vcr/cassette/http_interaction_list.rb
Expand Up @@ -6,8 +6,10 @@ def response_for(*a); nil; end
def has_interaction_matching?(*a); false; end
end

attr_reader :interactions, :request_matchers

def initialize(interactions, request_matchers, parent_list = NullList.new)
@interactions = interactions
@interactions = interactions.dup
@request_matchers = request_matchers
@parent_list = parent_list
@used_interactions = []
Expand Down
2 changes: 1 addition & 1 deletion lib/vcr/configuration.rb
Expand Up @@ -22,7 +22,7 @@ def cassette_library_dir=(cassette_library_dir)
attr_writer :default_cassette_options
def default_cassette_options
@default_cassette_options ||= {}
@default_cassette_options[:match_requests_on] ||= RequestMatcher::DEFAULT_MATCH_ATTRIBUTES
@default_cassette_options[:match_requests_on] ||= RequestMatcherRegistry::DEFAULT_MATCHERS
@default_cassette_options[:record] ||= :once
@default_cassette_options
end
Expand Down
88 changes: 0 additions & 88 deletions lib/vcr/http_stubbing_adapters/common.rb
Expand Up @@ -71,10 +71,6 @@ def set_http_connections_allowed_to_default
self.http_connections_allowed = VCR.configuration.allow_http_connections_when_no_cassette?
end

def raise_no_checkpoint_error(cassette)
raise ArgumentError.new("No checkpoint for #{cassette.inspect} could be found")
end

attr_writer :http_connections_allowed

def http_connections_allowed?
Expand All @@ -90,40 +86,6 @@ def uri_should_be_ignored?(uri)
ignored_hosts.include?(uri.host)
end

def stub_requests(http_interactions, match_attributes)
match_attributes_stack << match_attributes
grouped_responses(http_interactions, match_attributes).each do |request_matcher, responses|
request_matcher = request_matcher_with_normalized_uri(request_matcher)
queue = stub_queues[request_matcher]
responses.each { |res| queue << res }
end
end

def create_stubs_checkpoint(cassette)
checkpoints[cassette] = stub_queue_dup
end

def restore_stubs_checkpoint(cassette)
match_attributes_stack.pop
@stub_queues = checkpoints.delete(cassette) || raise_no_checkpoint_error(cassette)
end

def stubbed_response_for(request, remove = true)
return nil unless match_attributes_stack.any?
request_matcher = request.matcher(match_attributes_stack.last)
queue = stub_queues[request_matcher]

if remove && queue.size > 1
queue.shift
else
queue.first
end
end

def has_stubbed_response_for?(request)
!!stubbed_response_for(request, false)
end

def reset!
instance_variables.each do |ivar|
remove_instance_variable(ivar)
Expand All @@ -142,56 +104,6 @@ def raise_connections_disabled_error(request)
def ignored_hosts
@ignored_hosts ||= []
end

def checkpoints
@checkpoints ||= {}
end

def stub_queues
@stub_queues ||= hash_of_arrays
end

def match_attributes_stack
@match_attributes_stack ||= []
end

def stub_queue_dup
dup = hash_of_arrays

stub_queues.each do |k, v|
dup[k] = v.dup
end

dup
end

def hash_of_arrays
Hash.new { |h, k| h[k] = [] }
end

def grouped_responses(http_interactions, match_attributes)
responses = Hash.new { |h,k| h[k] = [] }

http_interactions.each do |i|
responses[i.request.matcher(match_attributes)] << i.response
end

responses
end

def normalize_uri(uri)
uri # adapters can override this
end

def request_matcher_with_normalized_uri(matcher)
normalized_uri = normalize_uri(matcher.request.uri)
return matcher unless matcher.request.uri != normalized_uri

request = matcher.request.dup
request.uri = normalized_uri

RequestMatcher.new(request, matcher.match_attributes)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/vcr/http_stubbing_adapters/excon.rb
Expand Up @@ -45,7 +45,7 @@ def request_should_be_ignored?

def stubbed_response
@stubbed_response ||= begin
if stubbed_response = VCR::HttpStubbingAdapters::Excon.stubbed_response_for(vcr_request)
if stubbed_response = VCR.http_interactions.response_for(vcr_request)
{
:body => stubbed_response.body,
:headers => normalized_headers(stubbed_response.headers || {}),
Expand Down
3 changes: 1 addition & 2 deletions lib/vcr/http_stubbing_adapters/fakeweb.rb
Expand Up @@ -24,7 +24,6 @@ class RequestHandler
def_delegators :"VCR::HttpStubbingAdapters::FakeWeb",
:enabled?,
:uri_should_be_ignored?,
:stubbed_response_for,
:http_connections_allowed?

def initialize(net_http, request, request_body = nil, &block)
Expand Down Expand Up @@ -95,7 +94,7 @@ def with_exclusive_fakeweb_stub(response)
end

def stubbed_response
@stubbed_response ||= stubbed_response_for(vcr_request)
@stubbed_response ||= VCR.http_interactions.response_for(vcr_request)
end

def vcr_request
Expand Down
7 changes: 1 addition & 6 deletions lib/vcr/http_stubbing_adapters/faraday.rb
Expand Up @@ -9,16 +9,11 @@ module Faraday
MIN_PATCH_LEVEL = '0.6.0'
MAX_MINOR_VERSION = '0.6'

private
private

def version
::Faraday::VERSION
end

def normalize_uri(uri)
# faraday normalizes +'s to %20's
uri.gsub('+', '%20')
end
end
end
end
Expand Down
5 changes: 3 additions & 2 deletions lib/vcr/http_stubbing_adapters/typhoeus.rb
Expand Up @@ -38,7 +38,6 @@ class RequestHandler
def_delegators :"VCR::HttpStubbingAdapters::Typhoeus",
:enabled?,
:uri_should_be_ignored?,
:stubbed_response_for,
:http_connections_allowed?,
:vcr_request_from

Expand Down Expand Up @@ -67,7 +66,7 @@ def vcr_request
end

def stubbed_response
@stubbed_response ||= stubbed_response_for(vcr_request)
@stubbed_response ||= VCR.http_interactions.response_for(vcr_request)
end

def typhoeus_response
Expand Down Expand Up @@ -116,6 +115,8 @@ def stubbed_response_headers
end
end

# TODO: add Typhoeus::Hydra.register_stub_finder API to Typhoeus
# so we can use that instead of monkey-patching it.
Typhoeus::Hydra::Stubbing::SharedMethods.class_eval do
undef find_stub_from_request
def find_stub_from_request(request)
Expand Down
8 changes: 2 additions & 6 deletions lib/vcr/http_stubbing_adapters/webmock.rb
Expand Up @@ -32,25 +32,21 @@ def response_hash_for(response)
}
end

def normalize_uri(uri)
::WebMock::Util::URI.normalize_uri(uri).to_s
end

GLOBAL_VCR_HOOK = ::WebMock::RequestStub.new(:any, /.*/).tap do |stub|
stub.with { |request|
vcr_request = vcr_request_from(request)

if uri_should_be_ignored?(request.uri)
false
elsif has_stubbed_response_for?(vcr_request)
elsif VCR.http_interactions.has_interaction_matching?(vcr_request)
true
elsif http_connections_allowed?
false
else
raise_connections_disabled_error(vcr_request)
end
}.to_return(lambda { |request|
response_hash_for stubbed_response_for(vcr_request_from(request))
response_hash_for VCR.http_interactions.response_for(vcr_request_from(request))
})
end

Expand Down
2 changes: 1 addition & 1 deletion lib/vcr/middleware/faraday.rb
Expand Up @@ -14,7 +14,7 @@ def call(env)

if VCR::HttpStubbingAdapters::Faraday.uri_should_be_ignored?(request.uri)
@app.call(env)
elsif response = VCR::HttpStubbingAdapters::Faraday.stubbed_response_for(request)
elsif response = VCR.http_interactions.response_for(request)
headers = env[:response_headers] ||= ::Faraday::Utils::Headers.new
headers.update response.headers if response.headers
env.update :status => response.status.code, :body => response.body
Expand Down

0 comments on commit 8ddc4a2

Please sign in to comment.