vcr 1.2.0 → 1.3.0
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.md +12 -0
- data/FullBuildRakeFile +22 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +46 -25
- data/Guardfile +9 -0
- data/README.md +10 -371
- data/Rakefile +6 -2
- data/TODO.md +4 -0
- data/features/support/env.rb +5 -1
- data/full_build +1 -0
- data/lib/vcr.rb +17 -7
- data/lib/vcr/basic_object.rb +39 -0
- data/lib/vcr/config.rb +4 -7
- data/lib/vcr/deprecations.rb +14 -0
- data/lib/vcr/http_stubbing_adapters/common.rb +44 -13
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +17 -28
- data/lib/vcr/http_stubbing_adapters/multi_object_proxy.rb +43 -0
- data/lib/vcr/http_stubbing_adapters/typhoeus.rb +101 -0
- data/lib/vcr/http_stubbing_adapters/webmock.rb +16 -37
- data/lib/vcr/internet_connection.rb +2 -1
- data/lib/vcr/structs.rb +32 -0
- data/lib/vcr/version.rb +1 -1
- data/spec/config_spec.rb +5 -25
- data/spec/deprecations_spec.rb +31 -3
- data/spec/extensions/net_http_spec.rb +1 -0
- data/spec/fixtures/1.9.1/fake_example.com_responses.yml +32 -1
- data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +32 -1
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +9 -24
- data/spec/http_stubbing_adapters/multi_object_proxy_spec.rb +101 -0
- data/spec/http_stubbing_adapters/typhoeus_spec.rb +28 -0
- data/spec/http_stubbing_adapters/webmock_spec.rb +8 -26
- data/spec/internet_connection_spec.rb +25 -7
- data/spec/spec_helper.rb +3 -1
- data/spec/structs_spec.rb +30 -6
- data/spec/support/http_library_adapters.rb +50 -15
- data/spec/support/http_stubbing_adapter.rb +65 -56
- data/spec/support/version_checker.rb +29 -0
- data/spec/vcr_spec.rb +30 -12
- data/vcr.gemspec +5 -4
- metadata +44 -15
@@ -6,24 +6,27 @@ module VCR
|
|
6
6
|
include VCR::HttpStubbingAdapters::Common
|
7
7
|
extend self
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def http_connections_allowed?
|
12
|
-
::WebMock::Config.instance.allow_net_connect
|
13
|
-
end
|
9
|
+
MINIMUM_VERSION = '1.4.0'
|
10
|
+
MAXIMUM_VERSION = '1.5'
|
14
11
|
|
15
12
|
def http_connections_allowed=(value)
|
16
13
|
::WebMock::Config.instance.allow_net_connect = value
|
17
14
|
end
|
18
15
|
|
19
|
-
def
|
20
|
-
|
16
|
+
def http_connections_allowed?
|
17
|
+
!!::WebMock::Config.instance.allow_net_connect
|
18
|
+
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
def ignore_localhost=(value)
|
21
|
+
::WebMock::Config.instance.allow_localhost = value
|
22
|
+
end
|
25
23
|
|
26
|
-
|
24
|
+
def ignore_localhost?
|
25
|
+
!!::WebMock::Config.instance.allow_localhost
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_requests(http_interactions, match_attributes)
|
29
|
+
grouped_responses(http_interactions, match_attributes).each do |request_matcher, responses|
|
27
30
|
stub = ::WebMock.stub_request(request_matcher.method || :any, request_matcher.uri)
|
28
31
|
|
29
32
|
with_hash = request_signature_hash(request_matcher)
|
@@ -41,23 +44,6 @@ module VCR
|
|
41
44
|
::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
|
42
45
|
end
|
43
46
|
|
44
|
-
def request_stubbed?(request, match_attributes)
|
45
|
-
matcher = request.matcher(match_attributes)
|
46
|
-
!!::WebMock.registered_request?(::WebMock::RequestSignature.new(matcher.method || :any, request.uri, request_signature_hash(matcher)))
|
47
|
-
end
|
48
|
-
|
49
|
-
def request_uri(net_http, request)
|
50
|
-
::WebMock::NetHTTPUtility.request_signature_from_request(net_http, request).uri.to_s
|
51
|
-
end
|
52
|
-
|
53
|
-
def ignore_localhost=(value)
|
54
|
-
::WebMock::Config.instance.allow_localhost = value
|
55
|
-
end
|
56
|
-
|
57
|
-
def ignore_localhost?
|
58
|
-
::WebMock::Config.instance.allow_localhost
|
59
|
-
end
|
60
|
-
|
61
47
|
private
|
62
48
|
|
63
49
|
def version
|
@@ -108,12 +94,5 @@ WebMock.after_request(:real_requests_only => true) do |request, response|
|
|
108
94
|
VCR.record_http_interaction(http_interaction)
|
109
95
|
end
|
110
96
|
|
111
|
-
|
112
|
-
|
113
|
-
class NetConnectNotAllowedError
|
114
|
-
def message
|
115
|
-
super + ". You can use VCR to automatically record this request and replay it later. For more details, see the VCR README at: http://github.com/myronmarston/vcr/tree/v#{VCR.version}"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
97
|
+
VCR::HttpStubbingAdapters::Common.add_vcr_info_to_exception_message(WebMock::NetConnectNotAllowedError)
|
98
|
+
|
data/lib/vcr/structs.rb
CHANGED
@@ -24,8 +24,40 @@ module VCR
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
module URINormalizer
|
28
|
+
DEFAULT_PORTS = {
|
29
|
+
'http' => 80,
|
30
|
+
'https' => 443
|
31
|
+
}
|
32
|
+
|
33
|
+
def initialize(*args)
|
34
|
+
super
|
35
|
+
normalize_uri
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def normalize_uri
|
41
|
+
u = begin
|
42
|
+
URI.parse(uri)
|
43
|
+
rescue URI::InvalidURIError
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
u.port ||= DEFAULT_PORTS[u.scheme]
|
48
|
+
|
49
|
+
# URI#to_s only includes the port if it's not the default
|
50
|
+
# but we want to always include it (since FakeWeb/WebMock
|
51
|
+
# urls have always included it). We force it to be included
|
52
|
+
# here by redefining default_port so that URI#to_s will include it.
|
53
|
+
def u.default_port; nil; end
|
54
|
+
self.uri = u.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
27
58
|
class Request < Struct.new(:method, :uri, :body, :headers)
|
28
59
|
include HeaderNormalizer
|
60
|
+
include URINormalizer
|
29
61
|
|
30
62
|
def self.from_net_http_request(net_http, request)
|
31
63
|
new(
|
data/lib/vcr/version.rb
CHANGED
data/spec/config_spec.rb
CHANGED
@@ -28,30 +28,10 @@ describe VCR::Config do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe '
|
32
|
-
it '
|
33
|
-
|
34
|
-
|
35
|
-
VCR::Config.http_stubbing_library.should == setting
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'when set to nil' do
|
40
|
-
before(:each) { VCR::Config.http_stubbing_library = nil }
|
41
|
-
|
42
|
-
{
|
43
|
-
[:FakeWeb, :WebMock] => nil,
|
44
|
-
[] => nil,
|
45
|
-
[:FakeWeb] => :fakeweb,
|
46
|
-
[:WebMock] => :webmock
|
47
|
-
}.each do |defined_constants, expected_return_value|
|
48
|
-
it "returns #{expected_return_value.inspect} when these constants are defined: #{defined_constants.inspect}" do
|
49
|
-
[:FakeWeb, :WebMock].each do |const|
|
50
|
-
Object.should_receive(:const_defined?).with(const).and_return(defined_constants.include?(const))
|
51
|
-
end
|
52
|
-
VCR::Config.http_stubbing_library.should == expected_return_value
|
53
|
-
end
|
54
|
-
end
|
31
|
+
describe '.stub_with' do
|
32
|
+
it 'stores the given symbols in http_stubbing_libraries' do
|
33
|
+
VCR::Config.stub_with :fakeweb, :typhoeus
|
34
|
+
VCR::Config.http_stubbing_libraries.should == [:fakeweb, :typhoeus]
|
55
35
|
end
|
56
36
|
end
|
57
37
|
|
@@ -73,4 +53,4 @@ describe VCR::Config do
|
|
73
53
|
end
|
74
54
|
end
|
75
55
|
end
|
76
|
-
end
|
56
|
+
end
|
data/spec/deprecations_spec.rb
CHANGED
@@ -1,8 +1,36 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Deprecations' do
|
4
|
+
disable_warnings
|
5
|
+
|
6
|
+
describe VCR::Config do
|
7
|
+
describe '.http_stubbing_library' do
|
8
|
+
before(:each) { described_class.stub_with :webmock, :typhoeus }
|
9
|
+
|
10
|
+
it 'returns the first configured stubbing library' do
|
11
|
+
described_class.http_stubbing_library.should == :webmock
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'prints a warning: WARNING: VCR::Config.http_stubbing_library is deprecated. Use VCR::Config.http_stubbing_libraries instead' do
|
15
|
+
described_class.should_receive(:warn).with("WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead.")
|
16
|
+
described_class.http_stubbing_library
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.http_stubbing_library=' do
|
21
|
+
it 'sets http_stubbing_libraries to an array of the given value' do
|
22
|
+
described_class.http_stubbing_library = :webmock
|
23
|
+
described_class.http_stubbing_libraries.should == [:webmock]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'prints a warning: WARNING: VCR::Config.http_stubbing_library= is deprecated. Use VCR::Config.stub_with instead' do
|
27
|
+
described_class.should_receive(:warn).with("WARNING: `VCR::Config.http_stubbing_library = :webmock` is deprecated. Use `VCR::Config.stub_with :webmock` instead.")
|
28
|
+
described_class.http_stubbing_library = :webmock
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
4
33
|
describe VCR::Cassette do
|
5
|
-
disable_warnings
|
6
34
|
subject { VCR::Cassette.new('cassette name') }
|
7
35
|
|
8
36
|
it 'raises an error when an :allow_real_http lambda is given' do
|
@@ -23,7 +51,7 @@ describe 'Deprecations' do
|
|
23
51
|
|
24
52
|
it "sets the http_stubbing_adapter's ignore_localhost attribute to true" do
|
25
53
|
subject
|
26
|
-
VCR.http_stubbing_adapter.ignore_localhost?.should
|
54
|
+
VCR.http_stubbing_adapter.ignore_localhost?.should == true
|
27
55
|
end
|
28
56
|
|
29
57
|
it "prints a warning: VCR's :allow_real_http cassette option is deprecated. Instead, use the ignore_localhost configuration option." do
|
@@ -49,4 +77,4 @@ describe 'Deprecations' do
|
|
49
77
|
end
|
50
78
|
end
|
51
79
|
end
|
52
|
-
end
|
80
|
+
end
|
@@ -4,6 +4,7 @@ describe "Net::HTTP Extensions" do
|
|
4
4
|
without_webmock_callbacks
|
5
5
|
|
6
6
|
let(:uri) { URI.parse('http://example.com') }
|
7
|
+
before(:each) { VCR.stub(:http_stubbing_adapter).and_return(VCR::HttpStubbingAdapters::FakeWeb) }
|
7
8
|
|
8
9
|
it 'checks if the request is stubbed using a VCR::Request' do
|
9
10
|
VCR.http_stubbing_adapter.should_receive(:request_stubbed?) do |request, _|
|
@@ -57,7 +57,38 @@
|
|
57
57
|
- "3285"
|
58
58
|
accept-ranges:
|
59
59
|
- bytes
|
60
|
-
:body: example.com get response with path=foo
|
60
|
+
:body: example.com get response 1 with path=foo
|
61
|
+
:http_version: "1.1"
|
62
|
+
- !ruby/struct:VCR::HTTPInteraction
|
63
|
+
:request: !ruby/struct:VCR::Request
|
64
|
+
:method: :get
|
65
|
+
:uri: http://example.com:80/foo
|
66
|
+
:body:
|
67
|
+
:headers:
|
68
|
+
:response: !ruby/struct:VCR::Response
|
69
|
+
:status: !ruby/struct:VCR::ResponseStatus
|
70
|
+
:code: 200
|
71
|
+
:message: OK
|
72
|
+
:headers:
|
73
|
+
etag:
|
74
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
75
|
+
last-modified:
|
76
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
77
|
+
connection:
|
78
|
+
- Keep-Alive
|
79
|
+
content-type:
|
80
|
+
- text/html; charset=UTF-8
|
81
|
+
date:
|
82
|
+
- Wed, 31 Mar 2010 02:43:23 GMT
|
83
|
+
server:
|
84
|
+
- Apache/2.2.3 (CentOS)
|
85
|
+
content-length:
|
86
|
+
- "438"
|
87
|
+
age:
|
88
|
+
- "3285"
|
89
|
+
accept-ranges:
|
90
|
+
- bytes
|
91
|
+
:body: example.com get response 2 with path=foo
|
61
92
|
:http_version: "1.1"
|
62
93
|
- !ruby/struct:VCR::HTTPInteraction
|
63
94
|
:request: !ruby/struct:VCR::Request
|
@@ -57,7 +57,38 @@
|
|
57
57
|
- "3285"
|
58
58
|
accept-ranges:
|
59
59
|
- bytes
|
60
|
-
body: example.com get response with path=foo
|
60
|
+
body: example.com get response 1 with path=foo
|
61
|
+
http_version: "1.1"
|
62
|
+
- !ruby/struct:VCR::HTTPInteraction
|
63
|
+
request: !ruby/struct:VCR::Request
|
64
|
+
method: :get
|
65
|
+
uri: http://example.com:80/foo
|
66
|
+
body:
|
67
|
+
headers:
|
68
|
+
response: !ruby/struct:VCR::Response
|
69
|
+
status: !ruby/struct:VCR::ResponseStatus
|
70
|
+
code: 200
|
71
|
+
message: OK
|
72
|
+
headers:
|
73
|
+
last-modified:
|
74
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
75
|
+
connection:
|
76
|
+
- Keep-Alive
|
77
|
+
etag:
|
78
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
79
|
+
content-type:
|
80
|
+
- text/html; charset=UTF-8
|
81
|
+
date:
|
82
|
+
- Wed, 31 Mar 2010 02:43:23 GMT
|
83
|
+
server:
|
84
|
+
- Apache/2.2.3 (CentOS)
|
85
|
+
content-length:
|
86
|
+
- "438"
|
87
|
+
age:
|
88
|
+
- "3285"
|
89
|
+
accept-ranges:
|
90
|
+
- bytes
|
91
|
+
body: example.com get response 2 with path=foo
|
61
92
|
http_version: "1.1"
|
62
93
|
- !ruby/struct:VCR::HTTPInteraction
|
63
94
|
request: !ruby/struct:VCR::Request
|
@@ -3,35 +3,20 @@ require 'spec_helper'
|
|
3
3
|
describe VCR::HttpStubbingAdapters::FakeWeb do
|
4
4
|
without_webmock_callbacks
|
5
5
|
|
6
|
-
|
6
|
+
it_behaves_like 'an http stubbing adapter', ['net/http'], [:method, :uri, :host, :path], :needs_net_http_extension
|
7
7
|
|
8
|
-
|
8
|
+
it_performs('version checking',
|
9
|
+
:valid => %w[ 1.3.0 1.3.1 1.3.99 ],
|
10
|
+
:too_low => %w[ 1.2.8 1.1.30 0.30.30 ],
|
11
|
+
:too_high => %w[ 1.4.0 1.10.0 2.0.0 ]
|
12
|
+
) do
|
9
13
|
disable_warnings
|
10
14
|
before(:each) { @orig_version = FakeWeb::VERSION }
|
11
15
|
after(:each) { FakeWeb::VERSION = @orig_version }
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
described_class.should_not_receive(:warn)
|
17
|
-
expect { described_class.check_version! }.to raise_error(/You are using FakeWeb #{version}. VCR requires version .* or greater/)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
%w( 1.3.0 1.3.1 1.3.99 ).each do |version|
|
22
|
-
it "does nothing when FakeWeb's version is #{version}" do
|
23
|
-
FakeWeb::VERSION = version
|
24
|
-
described_class.should_not_receive(:warn)
|
25
|
-
expect { described_class.check_version! }.to_not raise_error
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
%w( 1.4.0 1.10.0 2.0.0 ).each do |version|
|
30
|
-
it "prints a warning when FakeWeb's version is #{version}" do
|
31
|
-
FakeWeb::VERSION = version
|
32
|
-
described_class.should_receive(:warn).with(/VCR is known to work with FakeWeb ~> .*\./)
|
33
|
-
expect { described_class.check_version! }.to_not raise_error
|
34
|
-
end
|
17
|
+
# Cannot be regular method def as that raises a "dynamic constant assignment" error
|
18
|
+
define_method :stub_version do |version|
|
19
|
+
FakeWeb::VERSION = version
|
35
20
|
end
|
36
21
|
end
|
37
22
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module VCR
|
4
|
+
module HttpStubbingAdapters
|
5
|
+
describe MultiObjectProxy do
|
6
|
+
let(:mock1) { mock }
|
7
|
+
let(:mock2) { mock }
|
8
|
+
subject { described_class.new(mock1, mock2) }
|
9
|
+
|
10
|
+
it 'raises an error when it is created with no objects' do
|
11
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'raises an error when one of the objects is nil' do
|
15
|
+
expect { described_class.new(Object.new, nil) }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'is a basic object with very few of its own methods' do
|
19
|
+
inst_methods = described_class.instance_methods.map { |m| m.to_sym }
|
20
|
+
inst_methods.should_not include(:send, :object_id, :__id__)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#proxies_objects' do
|
24
|
+
it 'returns the proxied objects' do
|
25
|
+
subject.proxied_objects.should == [mock1, mock2]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#respond_to?' do
|
30
|
+
it 'responds to any method that any of the objects responds to' do
|
31
|
+
mock1.stub(:respond_to?).with(:foo).and_return(true)
|
32
|
+
mock1.stub(:respond_to?).with(:bar).and_return(false)
|
33
|
+
mock2.stub(:respond_to?).with(:bar).and_return(true)
|
34
|
+
mock2.stub(:respond_to?).with(:foo).and_return(false)
|
35
|
+
|
36
|
+
subject.respond_to?(:foo).should be_true
|
37
|
+
subject.respond_to?(:bar).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not respond to a method that none of the objects respond to' do
|
41
|
+
subject.respond_to?(:bazz).should be_false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'calling a method' do
|
46
|
+
it 'raises a no method error when none of the objects responds to the method' do
|
47
|
+
expect { subject.some_undefined_method }.to raise_error(NoMethodError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'properly proxies messages to a single object when only one object responds to the message' do
|
51
|
+
mock1.should_not respond_to(:request_stubbed?)
|
52
|
+
mock2.should_receive(:request_stubbed?).and_return(true)
|
53
|
+
|
54
|
+
subject.request_stubbed?.should == true
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'proxies messages to each object' do
|
58
|
+
mock1.should_receive(:stub_requests).with(:arg1, :arg2)
|
59
|
+
mock2.should_receive(:stub_requests).with(:arg1, :arg2)
|
60
|
+
|
61
|
+
subject.stub_requests(:arg1, :arg2)
|
62
|
+
end
|
63
|
+
|
64
|
+
[:http_connections_allowed?, :request_uri].each do |method|
|
65
|
+
context "for ##{method}" do
|
66
|
+
it 'raises an error if the the objects return different values' do
|
67
|
+
mock1.should_receive(method).and_return(:return_value_1)
|
68
|
+
mock2.should_receive(method).and_return(:return_value_2)
|
69
|
+
|
70
|
+
expect { subject.__send__(method) }.to raise_error(/proxied objects returned different values/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns the value returned by both objects when they return the same value' do
|
74
|
+
mock1.should_receive(method).and_return(:return_value_1)
|
75
|
+
mock2.should_receive(method).and_return(:return_value_1)
|
76
|
+
|
77
|
+
subject.__send__(method).should == :return_value_1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'for a non-predicate method' do
|
83
|
+
it 'does not raise an error when the objects have different return values' do
|
84
|
+
mock1.should_receive(:stub_requests).and_return(:val1)
|
85
|
+
mock2.should_receive(:stub_requests).and_return(:val2)
|
86
|
+
|
87
|
+
subject.stub_requests
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns nil regardless of the return values of the objects' do
|
91
|
+
mock1.should_receive(:stub_requests).and_return(:val1)
|
92
|
+
mock2.should_receive(:stub_requests).and_return(:val1)
|
93
|
+
|
94
|
+
subject.stub_requests.should be_nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|