vcr 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +27 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +119 -0
- data/README.md +3 -6
- data/Rakefile +70 -0
- data/benchmarks/http_stubbing_libraries.rb +59 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/regex_cassette.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +63 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +85 -0
- data/features/fixtures/vcr_cassettes/1.9.1/erb_cassette.yml +36 -0
- data/features/fixtures/vcr_cassettes/1.9.1/match_requests_on.yml +35 -0
- data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +32 -0
- data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/replay_localhost_cassette.yml +32 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/regex_cassette.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette2.yml +47 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/cucumber_tags/replay_cassette3.yml +85 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/erb_cassette.yml +36 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/match_requests_on.yml +35 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/nested_replay_cassette.yml +24 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/not_1.9.1/replay_localhost_cassette.yml +32 -0
- data/features/http_client.feature +16 -0
- data/features/net_http.feature +27 -0
- data/features/record_response.feature +66 -0
- data/features/replay_recorded_response.feature +96 -0
- data/features/step_definitions/http_client_steps.rb +7 -0
- data/features/step_definitions/net_http_steps.rb +37 -0
- data/features/step_definitions/vcr_steps.rb +240 -0
- data/features/support/env.rb +104 -0
- data/features/webmock.feature +26 -0
- data/lib/vcr.rb +2 -2
- data/lib/vcr/extensions/net_http.rb +0 -8
- data/lib/vcr/http_stubbing_adapters/common.rb +39 -0
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +74 -70
- data/lib/vcr/http_stubbing_adapters/webmock.rb +61 -62
- data/lib/vcr/version.rb +1 -1
- data/spec/cassette_spec.rb +280 -0
- data/spec/config_spec.rb +76 -0
- data/spec/cucumber_tags_spec.rb +55 -0
- data/spec/deprecations_spec.rb +52 -0
- data/spec/extensions/net_http_response_spec.rb +85 -0
- data/spec/extensions/net_http_spec.rb +77 -0
- data/spec/fixtures/1.9.1/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/1.9.1/cassette_spec/erb_with_no_vars.yml +32 -0
- data/spec/fixtures/1.9.1/cassette_spec/erb_with_vars.yml +32 -0
- data/spec/fixtures/1.9.1/cassette_spec/example.yml +110 -0
- data/spec/fixtures/1.9.1/cassette_spec/with_localhost_requests.yml +86 -0
- data/spec/fixtures/1.9.1/example_net_http.yml +14 -0
- data/spec/fixtures/1.9.1/example_net_http_request.yml +12 -0
- data/spec/fixtures/1.9.1/example_net_http_response.yml +25 -0
- data/spec/fixtures/1.9.1/fake_example.com_responses.yml +106 -0
- data/spec/fixtures/1.9.1/match_requests_on.yml +185 -0
- data/spec/fixtures/not_1.9.1/0_3_1_cassette.yml +29 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_no_vars.yml +32 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_vars.yml +32 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/example.yml +110 -0
- data/spec/fixtures/not_1.9.1/cassette_spec/with_localhost_requests.yml +86 -0
- data/spec/fixtures/not_1.9.1/example_net_http.yml +14 -0
- data/spec/fixtures/not_1.9.1/example_net_http_request.yml +12 -0
- data/spec/fixtures/not_1.9.1/example_net_http_response.yml +25 -0
- data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +106 -0
- data/spec/fixtures/not_1.9.1/match_requests_on.yml +185 -0
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +35 -0
- data/spec/http_stubbing_adapters/webmock_spec.rb +35 -0
- data/spec/request_matcher_spec.rb +194 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/structs_spec.rb +121 -0
- data/spec/support/disable_warnings.rb +12 -0
- data/spec/support/http_library_adapters.rb +272 -0
- data/spec/support/http_stubbing_adapter.rb +100 -0
- data/spec/support/pending_on_heroku.rb +14 -0
- data/spec/support/temp_cassette_library_dir.rb +16 -0
- data/spec/support/vcr_localhost_server.rb +53 -0
- data/spec/vcr_spec.rb +198 -0
- data/spec/version_spec.rb +11 -0
- data/vcr.gemspec +43 -0
- metadata +134 -73
- data/lib/vcr/http_stubbing_adapters/base.rb +0 -36
- data/lib/vcr/version.rbc +0 -572
@@ -0,0 +1,39 @@
|
|
1
|
+
module VCR
|
2
|
+
module HttpStubbingAdapters
|
3
|
+
autoload :FakeWeb, 'vcr/http_stubbing_adapters/fakeweb'
|
4
|
+
autoload :WebMock, 'vcr/http_stubbing_adapters/webmock'
|
5
|
+
|
6
|
+
class UnsupportedRequestMatchAttributeError < ArgumentError; end
|
7
|
+
|
8
|
+
module Common
|
9
|
+
def check_version!
|
10
|
+
version_too_low, version_too_high = compare_version
|
11
|
+
|
12
|
+
if version_too_low
|
13
|
+
raise "You are using #{library_name} #{version}. VCR requires version #{self::VERSION_REQUIREMENT} or greater."
|
14
|
+
elsif version_too_high
|
15
|
+
warn "You are using #{library_name} #{version}. VCR is known to work with #{library_name} ~> #{self::VERSION_REQUIREMENT}. It may not work with this version."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def compare_version
|
22
|
+
major, minor, patch = *version.split('.').map { |v| v.to_i }
|
23
|
+
req_major, req_minor, req_patch = *self::VERSION_REQUIREMENT.split('.').map { |v| v.to_i }
|
24
|
+
|
25
|
+
return true, false if major < req_major
|
26
|
+
return false, true if major > req_major
|
27
|
+
|
28
|
+
return true, false if minor < req_minor
|
29
|
+
return false, true if minor > req_minor
|
30
|
+
|
31
|
+
return patch < req_patch, false
|
32
|
+
end
|
33
|
+
|
34
|
+
def library_name
|
35
|
+
@library_name ||= self.to_s.split('::').last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -3,94 +3,98 @@ require 'vcr/extensions/net_http'
|
|
3
3
|
|
4
4
|
module VCR
|
5
5
|
module HttpStubbingAdapters
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def check_version!
|
11
|
-
unless meets_version_requirement?(::FakeWeb::VERSION, '1.2.8')
|
12
|
-
raise "You are using FakeWeb #{::FakeWeb::VERSION}. VCR requires version 1.2.8 or greater."
|
13
|
-
end
|
14
|
-
end
|
6
|
+
module FakeWeb
|
7
|
+
include VCR::HttpStubbingAdapters::Common
|
8
|
+
extend self
|
15
9
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
10
|
+
UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES = [:body, :headers].freeze
|
11
|
+
LOCALHOST_REGEX = %r|\Ahttps?://((\w+:)?\w+@)?(#{VCR::LOCALHOST_ALIASES.map { |a| Regexp.escape(a) }.join('|')})(:\d+)?/|i
|
19
12
|
|
20
|
-
|
21
|
-
::FakeWeb.allow_net_connect = value
|
22
|
-
end
|
13
|
+
VERSION_REQUIREMENT = '1.3.0'
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
http_interactions.each do |i|
|
29
|
-
requests[i.request.matcher(match_attributes)] += [i.response]
|
30
|
-
end
|
31
|
-
|
32
|
-
requests.each do |request_matcher, responses|
|
33
|
-
::FakeWeb.register_uri(
|
34
|
-
request_matcher.method || :any,
|
35
|
-
request_matcher.uri,
|
36
|
-
responses.map{ |r| response_hash(r) }
|
37
|
-
)
|
38
|
-
end
|
39
|
-
end
|
15
|
+
def http_connections_allowed?
|
16
|
+
!!::FakeWeb.allow_net_connect?("http://some.url/besides/localhost")
|
17
|
+
end
|
40
18
|
|
41
|
-
|
42
|
-
|
43
|
-
|
19
|
+
def http_connections_allowed=(value)
|
20
|
+
@http_connections_allowed = value
|
21
|
+
update_fakeweb_allow_net_connect
|
22
|
+
end
|
44
23
|
|
45
|
-
|
46
|
-
|
24
|
+
def stub_requests(http_interactions, match_attributes)
|
25
|
+
validate_match_attributes(match_attributes)
|
26
|
+
requests = Hash.new { |h,k| h[k] = [] }
|
27
|
+
|
28
|
+
http_interactions.each do |i|
|
29
|
+
requests[i.request.matcher(match_attributes)] << i.response
|
47
30
|
end
|
48
31
|
|
49
|
-
|
50
|
-
|
51
|
-
|
32
|
+
requests.each do |request_matcher, responses|
|
33
|
+
::FakeWeb.register_uri(
|
34
|
+
request_matcher.method || :any,
|
35
|
+
request_matcher.uri,
|
36
|
+
responses.map{ |r| response_hash(r) }
|
37
|
+
)
|
52
38
|
end
|
39
|
+
end
|
53
40
|
|
54
|
-
|
55
|
-
|
56
|
-
|
41
|
+
def create_stubs_checkpoint(checkpoint_name)
|
42
|
+
checkpoints[checkpoint_name] = ::FakeWeb::Registry.instance.uri_map.dup
|
43
|
+
end
|
57
44
|
|
58
|
-
|
59
|
-
|
45
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
46
|
+
::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
|
47
|
+
end
|
60
48
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
userinfo = ""
|
66
|
-
end
|
49
|
+
def request_stubbed?(request, match_attributes)
|
50
|
+
validate_match_attributes(match_attributes)
|
51
|
+
::FakeWeb.registered_uri?(request.method, request.uri)
|
52
|
+
end
|
67
53
|
|
68
|
-
|
69
|
-
|
54
|
+
def request_uri(net_http, request)
|
55
|
+
::FakeWeb::Utility.request_uri_as_string(net_http, request)
|
56
|
+
end
|
70
57
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
58
|
+
def ignore_localhost=(value)
|
59
|
+
@ignore_localhost = value
|
60
|
+
update_fakeweb_allow_net_connect
|
61
|
+
end
|
75
62
|
|
76
|
-
|
63
|
+
def ignore_localhost?
|
64
|
+
@ignore_localhost
|
65
|
+
end
|
77
66
|
|
78
|
-
|
79
|
-
@checkpoints ||= {}
|
80
|
-
end
|
67
|
+
private
|
81
68
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
def version
|
70
|
+
::FakeWeb::VERSION
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_fakeweb_allow_net_connect
|
74
|
+
::FakeWeb.allow_net_connect = if @http_connections_allowed
|
75
|
+
true
|
76
|
+
elsif @ignore_localhost
|
77
|
+
LOCALHOST_REGEX
|
78
|
+
else
|
79
|
+
false
|
87
80
|
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def checkpoints
|
84
|
+
@checkpoints ||= {}
|
85
|
+
end
|
86
|
+
|
87
|
+
def response_hash(response)
|
88
|
+
response.headers.merge(
|
89
|
+
:body => response.body,
|
90
|
+
:status => [response.status.code.to_s, response.status.message]
|
91
|
+
)
|
92
|
+
end
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
+
def validate_match_attributes(match_attributes)
|
95
|
+
invalid_attributes = match_attributes & UNSUPPORTED_REQUEST_MATCH_ATTRIBUTES
|
96
|
+
if invalid_attributes.size > 0
|
97
|
+
raise UnsupportedRequestMatchAttributeError.new("FakeWeb does not support matching requests on #{invalid_attributes.join(' or ')}")
|
94
98
|
end
|
95
99
|
end
|
96
100
|
end
|
@@ -3,86 +3,85 @@ require 'vcr/extensions/net_http'
|
|
3
3
|
|
4
4
|
module VCR
|
5
5
|
module HttpStubbingAdapters
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def check_version!
|
11
|
-
unless meets_version_requirement?(::WebMock.version, VERSION_REQUIREMENT)
|
12
|
-
raise "You are using WebMock #{::WebMock.version}. VCR requires version #{VERSION_REQUIREMENT} or greater."
|
13
|
-
end
|
14
|
-
end
|
6
|
+
module WebMock
|
7
|
+
include VCR::HttpStubbingAdapters::Common
|
8
|
+
extend self
|
15
9
|
|
16
|
-
|
17
|
-
::WebMock::Config.instance.allow_net_connect
|
18
|
-
end
|
10
|
+
VERSION_REQUIREMENT = '1.3.3'
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
def http_connections_allowed?
|
13
|
+
::WebMock::Config.instance.allow_net_connect
|
14
|
+
end
|
23
15
|
|
24
|
-
|
25
|
-
|
16
|
+
def http_connections_allowed=(value)
|
17
|
+
::WebMock::Config.instance.allow_net_connect = value
|
18
|
+
end
|
26
19
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
20
|
+
def stub_requests(http_interactions, match_attributes)
|
21
|
+
requests = Hash.new { |h,k| h[k] = [] }
|
30
22
|
|
31
|
-
|
32
|
-
|
23
|
+
http_interactions.each do |i|
|
24
|
+
requests[i.request.matcher(match_attributes)] << i.response
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
27
|
+
requests.each do |request_matcher, responses|
|
28
|
+
stub = ::WebMock.stub_request(request_matcher.method || :any, request_matcher.uri)
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
30
|
+
with_hash = request_signature_hash(request_matcher)
|
31
|
+
stub = stub.with(with_hash) if with_hash.size > 0
|
40
32
|
|
41
|
-
|
42
|
-
checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
|
33
|
+
stub.to_return(responses.map{ |r| response_hash(r) })
|
43
34
|
end
|
35
|
+
end
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
def create_stubs_checkpoint(checkpoint_name)
|
38
|
+
checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
|
39
|
+
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
41
|
+
def restore_stubs_checkpoint(checkpoint_name)
|
42
|
+
::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
|
43
|
+
end
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
def request_stubbed?(request, match_attributes)
|
46
|
+
matcher = request.matcher(match_attributes)
|
47
|
+
!!::WebMock.registered_request?(::WebMock::RequestSignature.new(matcher.method || :any, request.uri, request_signature_hash(matcher)))
|
48
|
+
end
|
57
49
|
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
def request_uri(net_http, request)
|
51
|
+
::WebMock::NetHTTPUtility.request_signature_from_request(net_http, request).uri.to_s
|
52
|
+
end
|
61
53
|
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
def ignore_localhost=(value)
|
55
|
+
::WebMock::Config.instance.allow_localhost = value
|
56
|
+
end
|
65
57
|
|
66
|
-
|
58
|
+
def ignore_localhost?
|
59
|
+
::WebMock::Config.instance.allow_localhost
|
60
|
+
end
|
67
61
|
|
68
|
-
|
69
|
-
signature = {}
|
70
|
-
signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
|
71
|
-
signature[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)
|
72
|
-
signature
|
73
|
-
end
|
62
|
+
private
|
74
63
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
:status => [response.status.code.to_i, response.status.message],
|
79
|
-
:headers => response.headers
|
80
|
-
}
|
81
|
-
end
|
64
|
+
def version
|
65
|
+
::WebMock.version
|
66
|
+
end
|
82
67
|
|
83
|
-
|
84
|
-
|
85
|
-
|
68
|
+
def request_signature_hash(request_matcher)
|
69
|
+
signature = {}
|
70
|
+
signature[:body] = request_matcher.body if request_matcher.match_requests_on?(:body)
|
71
|
+
signature[:headers] = request_matcher.headers if request_matcher.match_requests_on?(:headers)
|
72
|
+
signature
|
73
|
+
end
|
74
|
+
|
75
|
+
def response_hash(response)
|
76
|
+
{
|
77
|
+
:body => response.body,
|
78
|
+
:status => [response.status.code.to_i, response.status.message],
|
79
|
+
:headers => response.headers
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def checkpoints
|
84
|
+
@checkpoints ||= {}
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
data/lib/vcr/version.rb
CHANGED
@@ -0,0 +1,280 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe VCR::Cassette do
|
4
|
+
describe '#file' do
|
5
|
+
temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/file'), :assign_to_cassette_library_dir => true
|
6
|
+
|
7
|
+
it 'combines the cassette_library_dir with the cassette name' do
|
8
|
+
cassette = VCR::Cassette.new('the_file')
|
9
|
+
cassette.file.should == File.join(VCR::Config.cassette_library_dir, 'the_file.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'strips out disallowed characters so that it is a valid file name with no spaces' do
|
13
|
+
cassette = VCR::Cassette.new("\nthis \t! is-the_13212_file name")
|
14
|
+
cassette.file.should =~ /#{Regexp.escape('_this_is-the_13212_file_name.yml')}$/
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'keeps any path separators' do
|
18
|
+
cassette = VCR::Cassette.new("dir/file_name")
|
19
|
+
cassette.file.should =~ /#{Regexp.escape('dir/file_name.yml')}$/
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns nil if the cassette_library_dir is not set' do
|
23
|
+
VCR::Config.cassette_library_dir = nil
|
24
|
+
cassette = VCR::Cassette.new('the_file')
|
25
|
+
cassette.file.should be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#record_http_interaction' do
|
30
|
+
it 'adds the interaction to #recorded_interactions' do
|
31
|
+
cassette = VCR::Cassette.new(:test_cassette)
|
32
|
+
cassette.recorded_interactions.should == []
|
33
|
+
cassette.record_http_interaction(:the_interaction)
|
34
|
+
cassette.recorded_interactions.should == [:the_interaction]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#match_requests_on' do
|
39
|
+
before(:each) { VCR::Config.default_cassette_options.merge!(:match_requests_on => [:uri, :method]) }
|
40
|
+
|
41
|
+
it "returns the provided options" do
|
42
|
+
c = VCR::Cassette.new('example', :match_requests_on => [:uri])
|
43
|
+
c.match_requests_on.should == [:uri]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns a the default #match_requests_on when it has not been specified for the cassette" do
|
47
|
+
c = VCR::Cassette.new('example')
|
48
|
+
c.match_requests_on.should == [:uri, :method]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'on creation' do
|
53
|
+
it 'raises an error with a helpful message when loading an old unsupported cassette' do
|
54
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}")
|
55
|
+
lambda { VCR::Cassette.new('0_3_1_cassette') }.should raise_error(/The VCR cassette 0_3_1_cassette.yml uses an old format that is now deprecated/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises an error if given an invalid record mode" do
|
59
|
+
lambda { VCR::Cassette.new(:test, :record => :not_a_record_mode) }.should raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises an error if given invalid options' do
|
63
|
+
expect {
|
64
|
+
VCR::Cassette.new(:test, :invalid => :option)
|
65
|
+
}.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'creates a stubs checkpoint on the http_stubbing_adapter' do
|
69
|
+
VCR.http_stubbing_adapter.should_receive(:create_stubs_checkpoint).with('example').once
|
70
|
+
VCR::Cassette.new('example')
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'ERB support' do
|
74
|
+
before(:each) do
|
75
|
+
@orig_default_options = VCR::Config.default_cassette_options
|
76
|
+
end
|
77
|
+
|
78
|
+
after(:each) do
|
79
|
+
VCR::Config.default_cassette_options = @orig_default_options
|
80
|
+
end
|
81
|
+
|
82
|
+
def cassette_body(name, options = {})
|
83
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
84
|
+
VCR::Cassette.new(name, options.merge(:record => :new_episodes)).recorded_interactions.first.response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
it "compiles a template as ERB if the :erb option is passed as true" do
|
88
|
+
cassette_body('erb_with_no_vars', :erb => true).should == 'sum: 3'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "compiles a template as ERB if the default :erb option is true, and no option is passed to the cassette" do
|
92
|
+
VCR::Config.default_cassette_options = { :erb => true }
|
93
|
+
cassette_body('erb_with_no_vars').should == 'sum: 3'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "does not compile a template as ERB if the default :erb option is true, and :erb => false is passed to the cassette" do
|
97
|
+
VCR::Config.default_cassette_options = { :erb => true }
|
98
|
+
cassette_body('erb_with_no_vars', :erb => false).should == 'sum: <%= 1 + 2 %>'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "compiles a template as ERB if the :erb option is passed a hash" do
|
102
|
+
cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var3 => 'c', :var2 => 'b' }).should == 'var1: a; var2: b; var3: c'
|
103
|
+
end
|
104
|
+
|
105
|
+
it "does not compile a template as ERB if the :erb option is not used" do
|
106
|
+
cassette_body('erb_with_no_vars').should == 'sum: <%= 1 + 2 %>'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "raises a helpful error if the ERB template references variables that are not passed in the :erb hash" do
|
110
|
+
expect {
|
111
|
+
cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var2 => 'b' })
|
112
|
+
}.to raise_error(VCR::Cassette::MissingERBVariableError,
|
113
|
+
%{The ERB in the erb_with_vars.yml cassette file references undefined variable var3. } +
|
114
|
+
%{Pass it to the cassette using :erb => #{ { :var1 => 'a', :var2 => 'b' }.merge(:var3 => 'some value').inspect }.}
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises a helpful error if the ERB template references variables and :erb => true is passed" do
|
119
|
+
expect {
|
120
|
+
cassette_body('erb_with_vars', :erb => true)
|
121
|
+
}.to raise_error(VCR::Cassette::MissingERBVariableError,
|
122
|
+
%{The ERB in the erb_with_vars.yml cassette file references undefined variable var1. } +
|
123
|
+
%{Pass it to the cassette using :erb => {:var1=>"some value"}.}
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
VCR::Cassette::VALID_RECORD_MODES.each do |record_mode|
|
129
|
+
http_connections_allowed = (record_mode != :none)
|
130
|
+
load_interactions = (record_mode != :all)
|
131
|
+
|
132
|
+
context "when VCR::Config.default_cassette_options[:record] is :#{record_mode}" do
|
133
|
+
before(:each) { VCR::Config.default_cassette_options = { :record => record_mode } }
|
134
|
+
|
135
|
+
it "defaults the record mode to #{record_mode} when VCR::Config.default_cassette_options[:record] is #{record_mode}" do
|
136
|
+
cassette = VCR::Cassette.new(:test)
|
137
|
+
cassette.record_mode.should == record_mode
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when the record mode is :#{record_mode}" do
|
142
|
+
it "sets http_connections_allowed to #{http_connections_allowed} on the http stubbing adapter" do
|
143
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(http_connections_allowed)
|
144
|
+
VCR::Cassette.new(:name, :record => record_mode)
|
145
|
+
end
|
146
|
+
|
147
|
+
if load_interactions
|
148
|
+
|
149
|
+
[true, false].each do |ignore_localhost|
|
150
|
+
expected_uri_hosts = %w(example.com)
|
151
|
+
expected_uri_hosts += VCR::LOCALHOST_ALIASES unless ignore_localhost
|
152
|
+
|
153
|
+
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
|
154
|
+
VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost)
|
155
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
156
|
+
cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
|
157
|
+
cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it "loads the recorded interactions from the library yml file" do
|
162
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
163
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
164
|
+
|
165
|
+
cassette.should have(3).recorded_interactions
|
166
|
+
|
167
|
+
i1, i2, i3 = *cassette.recorded_interactions
|
168
|
+
|
169
|
+
i1.request.method.should == :get
|
170
|
+
i1.request.uri.should == 'http://example.com:80/'
|
171
|
+
i1.response.body.should =~ /You have reached this web page by typing.+example\.com/
|
172
|
+
|
173
|
+
i2.request.method.should == :get
|
174
|
+
i2.request.uri.should == 'http://example.com:80/foo'
|
175
|
+
i2.response.body.should =~ /foo was not found on this server/
|
176
|
+
|
177
|
+
i3.request.method.should == :get
|
178
|
+
i3.request.uri.should == 'http://example.com:80/'
|
179
|
+
i3.response.body.should =~ /Another example\.com response/
|
180
|
+
end
|
181
|
+
|
182
|
+
it "stubs the recorded requests with the http stubbing adapter" do
|
183
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
184
|
+
VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3, anything)
|
185
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "passes the :match_request_on option to #stub_requests" do
|
189
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
190
|
+
VCR.http_stubbing_adapter.should_receive(:stub_requests).with(anything, [:body, :headers])
|
191
|
+
cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
|
192
|
+
end
|
193
|
+
|
194
|
+
else
|
195
|
+
|
196
|
+
it "does not stub the recorded requests with the http stubbing adapter" do
|
197
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
198
|
+
VCR.http_stubbing_adapter.should_not_receive(:stub_requests)
|
199
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "does not load the recorded interactions from the library yml file" do
|
203
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
204
|
+
cassette = VCR::Cassette.new('example', :record => record_mode)
|
205
|
+
cassette.should have(0).recorded_interactions
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#eject' do
|
214
|
+
temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/cassette_spec_eject'), :assign_to_cassette_library_dir => true
|
215
|
+
|
216
|
+
[true, false].each do |orig_http_connections_allowed|
|
217
|
+
it "resets #{orig_http_connections_allowed} on the http stubbing adapter if it was originally #{orig_http_connections_allowed}" do
|
218
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed?).and_return(orig_http_connections_allowed)
|
219
|
+
cassette = VCR::Cassette.new(:name)
|
220
|
+
VCR.http_stubbing_adapter.should_receive(:http_connections_allowed=).with(orig_http_connections_allowed)
|
221
|
+
cassette.eject
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
it "writes the recorded interactions to disk as yaml" do
|
226
|
+
recorded_interactions = [
|
227
|
+
VCR::HTTPInteraction.new(:req_sig_1, :response_1),
|
228
|
+
VCR::HTTPInteraction.new(:req_sig_2, :response_2),
|
229
|
+
VCR::HTTPInteraction.new(:req_sig_3, :response_3)
|
230
|
+
]
|
231
|
+
|
232
|
+
cassette = VCR::Cassette.new(:eject_test)
|
233
|
+
cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
|
234
|
+
|
235
|
+
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
236
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
237
|
+
saved_recorded_interactions.should == recorded_interactions
|
238
|
+
end
|
239
|
+
|
240
|
+
it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
|
241
|
+
recorded_interactions = [VCR::HTTPInteraction.new(:the_request, :the_response)]
|
242
|
+
cassette = VCR::Cassette.new('subdirectory/test_cassette')
|
243
|
+
cassette.stub!(:recorded_interactions).and_return(recorded_interactions)
|
244
|
+
|
245
|
+
lambda { cassette.eject }.should change { File.exist?(cassette.file) }.from(false).to(true)
|
246
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
247
|
+
saved_recorded_interactions.should == recorded_interactions
|
248
|
+
end
|
249
|
+
|
250
|
+
it "writes both old and new recorded interactions to disk" do
|
251
|
+
file = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec/example.yml")
|
252
|
+
FileUtils.cp file, File.join(@temp_dir, 'previously_recorded_interactions.yml')
|
253
|
+
cassette = VCR::Cassette.new('previously_recorded_interactions')
|
254
|
+
cassette.should have(3).recorded_interactions
|
255
|
+
new_recorded_interaction = VCR::HTTPInteraction.new(:the_request, :the_response)
|
256
|
+
cassette.record_http_interaction(new_recorded_interaction)
|
257
|
+
cassette.eject
|
258
|
+
saved_recorded_interactions = File.open(cassette.file, "r") { |f| YAML.load(f.read) }
|
259
|
+
saved_recorded_interactions.should have(4).recorded_interactions
|
260
|
+
saved_recorded_interactions.last.should == new_recorded_interaction
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe '#eject for a cassette with previously recorded interactions' do
|
265
|
+
it "restore the stubs checkpoint on the http stubbing adapter" do
|
266
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
267
|
+
cassette = VCR::Cassette.new('example', :record => :none)
|
268
|
+
VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with('example')
|
269
|
+
cassette.eject
|
270
|
+
end
|
271
|
+
|
272
|
+
it "does not re-write to disk the previously recorded interactions if there are no new ones" do
|
273
|
+
VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
|
274
|
+
yaml_file = File.join(VCR::Config.cassette_library_dir, 'example.yml')
|
275
|
+
cassette = VCR::Cassette.new('example', :record => :none)
|
276
|
+
File.should_not_receive(:open).with(cassette.file, 'w')
|
277
|
+
lambda { cassette.eject }.should_not change { File.mtime(yaml_file) }
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|