Skip to content

Commit

Permalink
Changed the HTTP Stubbing Adapters to support the match_requests_on
Browse files Browse the repository at this point in the history
option.
  • Loading branch information
myronmarston committed Aug 12, 2010
1 parent f31f771 commit 2f34a5c
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 73 deletions.
4 changes: 3 additions & 1 deletion Rakefile
Expand Up @@ -2,7 +2,9 @@ require 'rubygems'
require 'rake' require 'rake'
require "rspec/core/rake_task" require "rspec/core/rake_task"


RSpec::Core::RakeTask.new(:spec) RSpec::Core::RakeTask.new(:spec) do |t|
t.spec_opts = ['--format', 'documentation']
end


desc "Run all examples using rcov" desc "Run all examples using rcov"
RSpec::Core::RakeTask.new :rcov => :cleanup_rcov_files do |t| RSpec::Core::RakeTask.new :rcov => :cleanup_rcov_files do |t|
Expand Down
2 changes: 1 addition & 1 deletion lib/vcr/cassette.rb
Expand Up @@ -99,7 +99,7 @@ def load_recorded_interactions
recorded_interactions.replace(@original_recorded_interactions) recorded_interactions.replace(@original_recorded_interactions)
end end


VCR.http_stubbing_adapter.stub_requests(recorded_interactions) VCR.http_stubbing_adapter.stub_requests(recorded_interactions, match_requests_on)
end end


@@struct_cache = Hash.new do |hash, attributes| @@struct_cache = Hash.new do |hash, attributes|
Expand Down
12 changes: 8 additions & 4 deletions lib/vcr/http_stubbing_adapters/fakeweb.rb
Expand Up @@ -19,15 +19,19 @@ def http_connections_allowed=(value)
::FakeWeb.allow_net_connect = value ::FakeWeb.allow_net_connect = value
end end


def stub_requests(http_interactions) def stub_requests(http_interactions, match_attributes = RequestMatcher::DEFAULT_MATCH_ATTRIBUTES)
requests = Hash.new([]) requests = Hash.new([])


http_interactions.each do |i| http_interactions.each do |i|
requests[[i.request.method, i.request.uri]] += [i.response] requests[i.request.matcher(match_attributes)] += [i.response]
end end


requests.each do |request, responses| requests.each do |request_matcher, responses|
::FakeWeb.register_uri(request.first, request.last, responses.map{ |r| response_hash(r) }) ::FakeWeb.register_uri(
request_matcher.method || :any,
request_matcher.uri,
responses.map{ |r| response_hash(r) }
)
end end
end end


Expand Down
20 changes: 13 additions & 7 deletions lib/vcr/http_stubbing_adapters/webmock.rb
Expand Up @@ -21,17 +21,23 @@ def http_connections_allowed=(value)
::WebMock::Config.instance.allow_net_connect = value ::WebMock::Config.instance.allow_net_connect = value
end end


def stub_requests(recorded_responses) def stub_requests(http_interactions, match_attributes = RequestMatcher::DEFAULT_MATCH_ATTRIBUTES)
requests = Hash.new([]) requests = Hash.new([])


# TODO: use the entire request signature, but make it configurable. http_interactions.each do |i|
recorded_responses.each do |rr| requests[i.request.matcher(match_attributes)] += [i.response]
requests[[rr.method, rr.uri]] += [rr.response]
end end


requests.each do |request, responses| requests.each do |request_matcher, responses|
::WebMock.stub_request(request.first, request.last). stub = ::WebMock.stub_request(request_matcher.method || :any, request_matcher.uri)
to_return(responses.map{ |r| response_hash(r) })
with_hash = {}
with_hash[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
with_hash[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)

stub = stub.with(with_hash) if with_hash.size > 0

stub.to_return(responses.map{ |r| response_hash(r) })
end end
end end


Expand Down
62 changes: 37 additions & 25 deletions spec/cassette_spec.rb
Expand Up @@ -144,11 +144,24 @@ def cassette_body(name, options = {})
VCR::Cassette.new(:name, :record => record_mode) VCR::Cassette.new(:name, :record => record_mode)
end end


it "#{load_interactions ? 'loads' : 'does not load'} the recorded interactions from the library yml file" do if load_interactions
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
cassette = VCR::Cassette.new('example', :record => record_mode) [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 = File.expand_path(File.dirname(__FILE__) + "/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
end
end

it "loads the recorded interactions from the library yml file" do
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
cassette = VCR::Cassette.new('example', :record => record_mode)


if load_interactions
cassette.should have(3).recorded_interactions cassette.should have(3).recorded_interactions


i1, i2, i3 = *cassette.recorded_interactions i1, i2, i3 = *cassette.recorded_interactions
Expand All @@ -164,35 +177,34 @@ def cassette_body(name, options = {})
i3.request.method.should == :get i3.request.method.should == :get
i3.request.uri.should == 'http://example.com:80/' i3.request.uri.should == 'http://example.com:80/'
i3.response.body.should =~ /Another example\.com response/ i3.response.body.should =~ /Another example\.com response/
else
cassette.should have(0).recorded_interactions
end end
end


it "#{load_interactions ? 'stubs' : 'does not stub'} the recorded requests with the http stubbing adapter" do it "stubs the recorded requests with the http stubbing adapter" do
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec") VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3, anything)
cassette = VCR::Cassette.new('example', :record => record_mode)
end


if load_interactions it "passes the :match_request_on option to #stub_requests" do
VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3) VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
else VCR.http_stubbing_adapter.should_receive(:stub_requests).with(anything, [:body, :headers])
VCR.http_stubbing_adapter.should_receive(:stub_requests).never cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
end end


cassette = VCR::Cassette.new('example', :record => record_mode) else
end


if load_interactions it "does not stub the recorded requests with the http stubbing adapter" do
[true, false].each do |ignore_localhost| VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
expected_uri_hosts = %w(example.com) VCR.http_stubbing_adapter.should_not_receive(:stub_requests)
expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost cassette = VCR::Cassette.new('example', :record => record_mode)
end


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 it "does not load the recorded interactions from the library yml file" do
VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost) VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec") cassette = VCR::Cassette.new('example', :record => record_mode)
cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode) cassette.should have(0).recorded_interactions
cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
end
end end

end end
end end
end end
Expand Down
155 changes: 155 additions & 0 deletions spec/fixtures/not_1.9.1/match_requests_on.yml
@@ -0,0 +1,155 @@
---
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/method
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: post method response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :get
uri: http://example.com:80/method
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: get method response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example1.com:80/host
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: example1.com host response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example2.com:80/host
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: example2.com host response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/uri1
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: uri1 response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/uri2
body:
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: uri2 response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/
body: param=val1
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: val1 body response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/
body: param=val2
headers:
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: val2 body response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/
body:
headers:
x-http-header1:
- val1
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: val1 header response
http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
request: !ruby/struct:VCR::Request
method: :post
uri: http://example.com:80/
body:
headers:
x-http-header1:
- val2
response: !ruby/struct:VCR::Response
status: !ruby/struct:VCR::ResponseStatus
code: 200
message: OK
headers:
etag:
- "\"24ec5-1b6-4059a80bfd280\""
body: val2 header response
http_version: "1.1"
2 changes: 1 addition & 1 deletion spec/http_stubbing_adapters/fakeweb_spec.rb
Expand Up @@ -2,7 +2,7 @@


describe VCR::HttpStubbingAdapters::FakeWeb do describe VCR::HttpStubbingAdapters::FakeWeb do
it_should_behave_like 'an http stubbing adapter' it_should_behave_like 'an http stubbing adapter'
it_should_behave_like 'an http stubbing adapter that supports Net::HTTP' it_should_behave_like 'an http stubbing adapter that supports Net::HTTP', :method, :uri, :host


describe '#check_version!' do describe '#check_version!' do
disable_warnings disable_warnings
Expand Down
10 changes: 6 additions & 4 deletions spec/http_stubbing_adapters/webmock_spec.rb
@@ -1,23 +1,25 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')


describe VCR::HttpStubbingAdapters::WebMock do describe VCR::HttpStubbingAdapters::WebMock do
supported_match_attributes = [:method, :uri, :host, :body, :headers]

it_should_behave_like 'an http stubbing adapter' it_should_behave_like 'an http stubbing adapter'
it_should_behave_like 'an http stubbing adapter that supports Net::HTTP' it_should_behave_like 'an http stubbing adapter that supports Net::HTTP', *supported_match_attributes


context "using patron" do context "using patron" do
it_should_behave_like 'an http stubbing adapter that supports some HTTP library' do it_should_behave_like 'an http stubbing adapter that supports some HTTP library', *supported_match_attributes do
include PatronAdapter include PatronAdapter
end end
end unless RUBY_PLATFORM =~ /java/ end unless RUBY_PLATFORM =~ /java/


context "using httpclient" do context "using httpclient" do
it_should_behave_like 'an http stubbing adapter that supports some HTTP library' do it_should_behave_like 'an http stubbing adapter that supports some HTTP library', *supported_match_attributes do
include HTTPClientAdapter include HTTPClientAdapter
end end
end end


context "using em-http-request" do context "using em-http-request" do
it_should_behave_like 'an http stubbing adapter that supports some HTTP library' do it_should_behave_like 'an http stubbing adapter that supports some HTTP library', *supported_match_attributes do
include EmHTTPRequestAdapter include EmHTTPRequestAdapter
end end
end unless RUBY_PLATFORM =~ /java/ end unless RUBY_PLATFORM =~ /java/
Expand Down

0 comments on commit 2f34a5c

Please sign in to comment.