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.
Files changed (40) hide show
  1. data/CHANGELOG.md +12 -0
  2. data/FullBuildRakeFile +22 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +46 -25
  5. data/Guardfile +9 -0
  6. data/README.md +10 -371
  7. data/Rakefile +6 -2
  8. data/TODO.md +4 -0
  9. data/features/support/env.rb +5 -1
  10. data/full_build +1 -0
  11. data/lib/vcr.rb +17 -7
  12. data/lib/vcr/basic_object.rb +39 -0
  13. data/lib/vcr/config.rb +4 -7
  14. data/lib/vcr/deprecations.rb +14 -0
  15. data/lib/vcr/http_stubbing_adapters/common.rb +44 -13
  16. data/lib/vcr/http_stubbing_adapters/fakeweb.rb +17 -28
  17. data/lib/vcr/http_stubbing_adapters/multi_object_proxy.rb +43 -0
  18. data/lib/vcr/http_stubbing_adapters/typhoeus.rb +101 -0
  19. data/lib/vcr/http_stubbing_adapters/webmock.rb +16 -37
  20. data/lib/vcr/internet_connection.rb +2 -1
  21. data/lib/vcr/structs.rb +32 -0
  22. data/lib/vcr/version.rb +1 -1
  23. data/spec/config_spec.rb +5 -25
  24. data/spec/deprecations_spec.rb +31 -3
  25. data/spec/extensions/net_http_spec.rb +1 -0
  26. data/spec/fixtures/1.9.1/fake_example.com_responses.yml +32 -1
  27. data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +32 -1
  28. data/spec/http_stubbing_adapters/fakeweb_spec.rb +9 -24
  29. data/spec/http_stubbing_adapters/multi_object_proxy_spec.rb +101 -0
  30. data/spec/http_stubbing_adapters/typhoeus_spec.rb +28 -0
  31. data/spec/http_stubbing_adapters/webmock_spec.rb +8 -26
  32. data/spec/internet_connection_spec.rb +25 -7
  33. data/spec/spec_helper.rb +3 -1
  34. data/spec/structs_spec.rb +30 -6
  35. data/spec/support/http_library_adapters.rb +50 -15
  36. data/spec/support/http_stubbing_adapter.rb +65 -56
  37. data/spec/support/version_checker.rb +29 -0
  38. data/spec/vcr_spec.rb +30 -12
  39. data/vcr.gemspec +5 -4
  40. metadata +44 -15
@@ -6,24 +6,27 @@ module VCR
6
6
  include VCR::HttpStubbingAdapters::Common
7
7
  extend self
8
8
 
9
- VERSION_REQUIREMENT = '1.4.0'
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 stub_requests(http_interactions, match_attributes)
20
- requests = Hash.new { |h,k| h[k] = [] }
16
+ def http_connections_allowed?
17
+ !!::WebMock::Config.instance.allow_net_connect
18
+ end
21
19
 
22
- http_interactions.each do |i|
23
- requests[i.request.matcher(match_attributes)] << i.response
24
- end
20
+ def ignore_localhost=(value)
21
+ ::WebMock::Config.instance.allow_localhost = value
22
+ end
25
23
 
26
- requests.each do |request_matcher, responses|
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
- if defined?(WebMock::NetConnectNotAllowedError)
112
- module WebMock
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
+
@@ -7,7 +7,8 @@ module VCR
7
7
  EXAMPLE_HOST = "example.com"
8
8
 
9
9
  def available?
10
- @available ||= Ping.pingecho(EXAMPLE_HOST, 1, 80)
10
+ @available = Ping.pingecho(EXAMPLE_HOST, 1, 80) unless defined?(@available)
11
+ @available
11
12
  end
12
13
  end
13
14
  end
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
@@ -3,7 +3,7 @@ module VCR
3
3
 
4
4
  def version
5
5
  @version ||= begin
6
- string = '1.2.0'
6
+ string = '1.3.0'
7
7
 
8
8
  def string.parts; VCR.version.split('.').map { |p| p.to_i }; end
9
9
  def string.major; parts[0]; end
data/spec/config_spec.rb CHANGED
@@ -28,30 +28,10 @@ describe VCR::Config do
28
28
  end
29
29
  end
30
30
 
31
- describe '#http_stubbing_library' do
32
- it 'returns the configured value' do
33
- [:fakeweb, :webmock].each do |setting|
34
- VCR::Config.http_stubbing_library = setting
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
@@ -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 be_true
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
- it_should_behave_like 'an http stubbing adapter', ['net/http'], [:method, :uri, :host, :path]
6
+ it_behaves_like 'an http stubbing adapter', ['net/http'], [:method, :uri, :host, :path], :needs_net_http_extension
7
7
 
8
- describe '#check_version!' do
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
- %w( 1.2.8 1.1.30 0.30.30 ).each do |version|
14
- it "raises an error when FakeWeb's version is #{version}" do
15
- FakeWeb::VERSION = version
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
+